mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-03 00:15:35 +00:00
feat: initial custom biome implementation
This commit is contained in:
parent
5e1c9d8ebe
commit
858adfe866
@ -4,13 +4,21 @@ import com.dfsek.tectonic.api.TypeRegistry;
|
|||||||
import com.dfsek.tectonic.api.loader.type.TypeLoader;
|
import com.dfsek.tectonic.api.loader.type.TypeLoader;
|
||||||
|
|
||||||
import com.dfsek.terra.AbstractPlatform;
|
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.block.state.BlockState;
|
||||||
import com.dfsek.terra.api.entity.EntityType;
|
import com.dfsek.terra.api.entity.EntityType;
|
||||||
import com.dfsek.terra.api.event.events.platform.PlatformInitializationEvent;
|
import com.dfsek.terra.api.event.events.platform.PlatformInitializationEvent;
|
||||||
import com.dfsek.terra.api.handle.ItemHandle;
|
import com.dfsek.terra.api.handle.ItemHandle;
|
||||||
import com.dfsek.terra.api.handle.WorldHandle;
|
import com.dfsek.terra.api.handle.WorldHandle;
|
||||||
import com.dfsek.terra.api.world.biome.PlatformBiome;
|
import com.dfsek.terra.api.world.biome.PlatformBiome;
|
||||||
|
import com.dfsek.terra.minestom.addon.MinestomAddon;
|
||||||
|
import com.dfsek.terra.minestom.config.BiomeAdditionsSoundTemplate;
|
||||||
|
import com.dfsek.terra.minestom.config.BiomeParticleConfigTemplate;
|
||||||
import com.dfsek.terra.minestom.biome.MinestomBiomeLoader;
|
import com.dfsek.terra.minestom.biome.MinestomBiomeLoader;
|
||||||
|
import com.dfsek.terra.minestom.config.KeyLoader;
|
||||||
|
import com.dfsek.terra.minestom.config.BiomeMoodSoundTemplate;
|
||||||
|
import com.dfsek.terra.minestom.config.RGBLikeLoader;
|
||||||
|
import com.dfsek.terra.minestom.config.SoundEventTemplate;
|
||||||
import com.dfsek.terra.minestom.entity.MinestomEntityType;
|
import com.dfsek.terra.minestom.entity.MinestomEntityType;
|
||||||
import com.dfsek.terra.minestom.item.MinestomItemHandle;
|
import com.dfsek.terra.minestom.item.MinestomItemHandle;
|
||||||
import com.dfsek.terra.minestom.world.MinestomChunkGeneratorWrapper;
|
import com.dfsek.terra.minestom.world.MinestomChunkGeneratorWrapper;
|
||||||
@ -18,13 +26,18 @@ import com.dfsek.terra.minestom.world.MinestomWorldHandle;
|
|||||||
|
|
||||||
import com.dfsek.terra.minestom.world.TerraMinestomWorldBuilder;
|
import com.dfsek.terra.minestom.world.TerraMinestomWorldBuilder;
|
||||||
|
|
||||||
|
import net.kyori.adventure.key.Key;
|
||||||
|
import net.kyori.adventure.util.RGBLike;
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.instance.Instance;
|
import net.minestom.server.instance.Instance;
|
||||||
|
import net.minestom.server.sound.SoundEvent;
|
||||||
|
import net.minestom.server.world.biome.BiomeEffects;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
public final class TerraMinestomPlatform extends AbstractPlatform {
|
public final class TerraMinestomPlatform extends AbstractPlatform {
|
||||||
@ -50,8 +63,14 @@ public final class TerraMinestomPlatform extends AbstractPlatform {
|
|||||||
super.register(registry);
|
super.register(registry);
|
||||||
registry
|
registry
|
||||||
.registerLoader(PlatformBiome.class, biomeTypeLoader)
|
.registerLoader(PlatformBiome.class, biomeTypeLoader)
|
||||||
|
.registerLoader(RGBLike.class, new RGBLikeLoader())
|
||||||
|
.registerLoader(Key.class, new KeyLoader())
|
||||||
.registerLoader(EntityType.class, (TypeLoader<EntityType>) (annotatedType, o, configLoader, depthTracker) -> new MinestomEntityType((String) o))
|
.registerLoader(EntityType.class, (TypeLoader<EntityType>) (annotatedType, o, configLoader, depthTracker) -> new MinestomEntityType((String) o))
|
||||||
.registerLoader(BlockState.class, (TypeLoader<BlockState>) (annotatedType, o, configLoader, depthTracker) -> worldHandle.createBlockState((String) o));
|
.registerLoader(BlockState.class, (TypeLoader<BlockState>) (annotatedType, o, configLoader, depthTracker) -> worldHandle.createBlockState((String) o))
|
||||||
|
.registerLoader(BiomeEffects.Particle.class, BiomeParticleConfigTemplate::new)
|
||||||
|
.registerLoader(BiomeEffects.MoodSound.class, BiomeMoodSoundTemplate::new)
|
||||||
|
.registerLoader(BiomeEffects.AdditionsSound.class, BiomeAdditionsSoundTemplate::new)
|
||||||
|
.registerLoader(SoundEvent.class, SoundEventTemplate::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -103,4 +122,9 @@ public final class TerraMinestomPlatform extends AbstractPlatform {
|
|||||||
public TerraMinestomWorldBuilder worldBuilder() {
|
public TerraMinestomWorldBuilder worldBuilder() {
|
||||||
return new TerraMinestomWorldBuilder(this, MinecraftServer.getInstanceManager().createInstanceContainer());
|
return new TerraMinestomWorldBuilder(this, MinecraftServer.getInstanceManager().createInstanceContainer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Iterable<BaseAddon> platformAddon() {
|
||||||
|
return List.of(new MinestomAddon(this));
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.dfsek.terra.minestom.addon;
|
||||||
|
|
||||||
|
import ca.solostudios.strata.Versions;
|
||||||
|
import ca.solostudios.strata.version.Version;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.addon.BaseAddon;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent;
|
||||||
|
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
import com.dfsek.terra.minestom.TerraMinestomPlatform;
|
||||||
|
|
||||||
|
import com.dfsek.terra.minestom.config.VanillaBiomeProperties;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
|
||||||
|
public class MinestomAddon implements BaseAddon {
|
||||||
|
private static final Version VERSION = Versions.getVersion(1, 0, 0);
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(MinestomAddon.class);
|
||||||
|
private final TerraMinestomPlatform minestomPlatform;
|
||||||
|
|
||||||
|
public MinestomAddon(TerraMinestomPlatform minestomPlatform) {
|
||||||
|
this.minestomPlatform = minestomPlatform;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
minestomPlatform.getEventManager()
|
||||||
|
.getHandler(FunctionalEventHandler.class)
|
||||||
|
.register(this, ConfigurationLoadEvent.class)
|
||||||
|
.then(event -> {
|
||||||
|
if(event.is(Biome.class)) {
|
||||||
|
event.getLoadedObject(Biome.class).getContext().put(event.load(new VanillaBiomeProperties()));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.global();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Version getVersion() { return VERSION; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getID() { return "terra-minestom"; }
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.dfsek.terra.minestom.biome;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
|
||||||
|
public interface BiomeFactory {
|
||||||
|
NativeBiome create(ConfigPack pack, Biome source);
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
package com.dfsek.terra.minestom.biome;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
|
import com.dfsek.terra.api.registry.key.RegistryKey;
|
||||||
|
import com.dfsek.terra.minestom.config.VanillaBiomeProperties;
|
||||||
|
|
||||||
|
import net.kyori.adventure.key.Key;
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.color.Color;
|
||||||
|
import net.minestom.server.registry.DynamicRegistry;
|
||||||
|
import net.minestom.server.world.biome.Biome;
|
||||||
|
import net.minestom.server.world.biome.BiomeEffects;
|
||||||
|
import org.intellij.lang.annotations.Subst;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
||||||
|
public class MinestomCustomBiomeFactory implements BiomeFactory {
|
||||||
|
private final DynamicRegistry<Biome> biomeRegistry = MinecraftServer.getBiomeRegistry();
|
||||||
|
private final @NotNull Biome plainsBiome = Objects.requireNonNull(biomeRegistry.get(Key.key("minecraft:plains")));
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NativeBiome create(ConfigPack pack, com.dfsek.terra.api.world.biome.Biome source) {
|
||||||
|
VanillaBiomeProperties properties = source.getContext().get(VanillaBiomeProperties.class);
|
||||||
|
DynamicRegistry.Key<Biome> parentKey = ((MinestomBiome) source.getPlatformBiome()).getHandle();
|
||||||
|
Biome parent = mergeNullable(biomeRegistry.get(parentKey), plainsBiome);
|
||||||
|
BiomeEffects parentEffects = parent.effects();
|
||||||
|
Key key = Key.key("terra", createBiomeID(pack, source.getID()));
|
||||||
|
|
||||||
|
BiomeEffects.Builder effectsBuilder = BiomeEffects.builder()
|
||||||
|
.fogColor(mergeNullable(properties.getFogColor(), parentEffects.fogColor()))
|
||||||
|
.skyColor(mergeNullable(properties.getSkyColor(), parentEffects.skyColor()))
|
||||||
|
.waterColor(mergeNullable(properties.getWaterColor(), parentEffects.waterColor()))
|
||||||
|
.waterFogColor(mergeNullable(properties.getWaterFogColor(), parentEffects.waterFogColor()))
|
||||||
|
.foliageColor(mergeNullable(properties.getFoliageColor(), parentEffects.foliageColor()))
|
||||||
|
.grassColor(mergeNullable(properties.getGrassColor(), parentEffects.grassColor()))
|
||||||
|
.grassColorModifier(mergeNullable(properties.getGrassColorModifier(), parentEffects.grassColorModifier()))
|
||||||
|
.biomeParticle(mergeNullable(properties.getParticleConfig(), parentEffects.biomeParticle()))
|
||||||
|
.ambientSound(mergeNullable(properties.getLoopSound(), parentEffects.ambientSound()))
|
||||||
|
.moodSound(mergeNullable(properties.getMoodSound(), parentEffects.moodSound()))
|
||||||
|
.additionsSound(mergeNullable(properties.getAdditionsSound(), parentEffects.additionsSound()))
|
||||||
|
// TODO music
|
||||||
|
.music(parentEffects.music())
|
||||||
|
.musicVolume(parentEffects.musicVolume());
|
||||||
|
|
||||||
|
if (effectsBuilder.build().equals(BiomeEffects.PLAINS_EFFECTS)) {
|
||||||
|
effectsBuilder.fogColor(new Color(0xC0D8FE)); // circumvent a minestom bug
|
||||||
|
}
|
||||||
|
|
||||||
|
Biome target = Biome.builder()
|
||||||
|
.downfall(mergeNullable(properties.getDownfall(), parent.downfall()))
|
||||||
|
.hasPrecipitation(mergeNullable(properties.getPrecipitation(), parent.hasPrecipitation()))
|
||||||
|
.temperature(mergeNullable(properties.getTemperature(), parent.temperature()))
|
||||||
|
.temperatureModifier(mergeNullable(properties.getTemperatureModifier(), parent.temperatureModifier()))
|
||||||
|
.effects(effectsBuilder.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
DynamicRegistry.Key<Biome> registryKey = MinecraftServer.getBiomeRegistry().register(key, target);
|
||||||
|
return new NativeBiome(key, registryKey, source.getID(), target);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> T mergeNullable(T first, T second) {
|
||||||
|
if (first == null) return second;
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subst("value")
|
||||||
|
protected static String createBiomeID(ConfigPack pack, String biomeId) {
|
||||||
|
return pack.getID().toLowerCase() + "/" + biomeId.toLowerCase(Locale.ROOT);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package com.dfsek.terra.minestom.biome;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
|
||||||
|
public class MinestomCustomBiomePool {
|
||||||
|
private final HashMap<String, NativeBiome> biomes = new HashMap<>();
|
||||||
|
private final MinestomCustomBiomeFactory factory;
|
||||||
|
private final ConfigPack configPack;
|
||||||
|
|
||||||
|
public MinestomCustomBiomePool(ConfigPack configPack, MinestomCustomBiomeFactory factory) {
|
||||||
|
this.configPack = configPack;
|
||||||
|
this.factory = factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NativeBiome getBiome(Biome source) {
|
||||||
|
NativeBiome nativeBiome = biomes.get(source.getID());
|
||||||
|
if(nativeBiome != null) return nativeBiome;
|
||||||
|
nativeBiome = factory.create(configPack, source);
|
||||||
|
biomes.put(source.getID(), nativeBiome);
|
||||||
|
return nativeBiome;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void preloadBiomes(Iterable<Biome> biomesToLoad) {
|
||||||
|
biomesToLoad
|
||||||
|
.forEach(biome -> {
|
||||||
|
if(!this.biomes.containsKey(biome.getID())) {
|
||||||
|
this.biomes.put(biome.getID(), factory.create(configPack, biome));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void invalidate() {
|
||||||
|
biomes.clear();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.dfsek.terra.minestom.biome;
|
||||||
|
|
||||||
|
import net.kyori.adventure.key.Key;
|
||||||
|
import net.minestom.server.registry.DynamicRegistry;
|
||||||
|
import net.minestom.server.world.biome.Biome;
|
||||||
|
|
||||||
|
|
||||||
|
public record NativeBiome(Key key, DynamicRegistry.Key<Biome> registry, String id, Biome biome) {
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.dfsek.terra.minestom.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 net.minestom.server.sound.SoundEvent;
|
||||||
|
import net.minestom.server.world.biome.BiomeEffects;
|
||||||
|
|
||||||
|
|
||||||
|
public class BiomeAdditionsSoundTemplate implements ObjectTemplate<BiomeEffects.AdditionsSound> {
|
||||||
|
@Value("sound")
|
||||||
|
@Default
|
||||||
|
private SoundEvent sound = null;
|
||||||
|
|
||||||
|
@Value("sound-chance")
|
||||||
|
@Default
|
||||||
|
private Double soundChance = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeEffects.AdditionsSound get() {
|
||||||
|
if(sound == null) return null;
|
||||||
|
return new BiomeEffects.AdditionsSound(sound, soundChance);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.dfsek.terra.minestom.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 net.minestom.server.sound.SoundEvent;
|
||||||
|
import net.minestom.server.world.biome.BiomeEffects;
|
||||||
|
|
||||||
|
|
||||||
|
public class BiomeMoodSoundTemplate implements ObjectTemplate<BiomeEffects.MoodSound> {
|
||||||
|
@Value("sound")
|
||||||
|
@Default
|
||||||
|
private SoundEvent sound = null;
|
||||||
|
|
||||||
|
@Value("cultivation-ticks")
|
||||||
|
@Default
|
||||||
|
private Integer soundCultivationTicks = null;
|
||||||
|
|
||||||
|
@Value("spawn-range")
|
||||||
|
@Default
|
||||||
|
private Integer soundSpawnRange = null;
|
||||||
|
|
||||||
|
@Value("extra-distance")
|
||||||
|
@Default
|
||||||
|
private Double soundExtraDistance = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeEffects.MoodSound get() {
|
||||||
|
if(sound == null) return null;
|
||||||
|
return new BiomeEffects.MoodSound(
|
||||||
|
sound,
|
||||||
|
soundCultivationTicks,
|
||||||
|
soundSpawnRange,
|
||||||
|
soundExtraDistance
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.dfsek.terra.minestom.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 net.minestom.server.particle.Particle;
|
||||||
|
import net.minestom.server.world.biome.BiomeEffects;
|
||||||
|
|
||||||
|
|
||||||
|
public class BiomeParticleConfigTemplate implements ObjectTemplate<BiomeEffects.Particle> {
|
||||||
|
@Value("particle")
|
||||||
|
@Default
|
||||||
|
private String particle = null;
|
||||||
|
|
||||||
|
@Value("probability")
|
||||||
|
@Default
|
||||||
|
private Float probability = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeEffects.Particle get() {
|
||||||
|
if(particle == null || probability == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BiomeEffects.Particle(
|
||||||
|
probability,
|
||||||
|
Particle.fromKey(particle)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.dfsek.terra.minestom.config;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.depth.DepthTracker;
|
||||||
|
import com.dfsek.tectonic.api.exception.LoadException;
|
||||||
|
import com.dfsek.tectonic.api.loader.ConfigLoader;
|
||||||
|
import com.dfsek.tectonic.api.loader.type.TypeLoader;
|
||||||
|
import net.kyori.adventure.key.InvalidKeyException;
|
||||||
|
import net.kyori.adventure.key.Key;
|
||||||
|
import org.intellij.lang.annotations.Subst;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.AnnotatedType;
|
||||||
|
|
||||||
|
|
||||||
|
public class KeyLoader implements TypeLoader<Key> {
|
||||||
|
@Override
|
||||||
|
public Key load(
|
||||||
|
@NotNull AnnotatedType annotatedType,
|
||||||
|
@NotNull Object o,
|
||||||
|
@NotNull ConfigLoader configLoader,
|
||||||
|
DepthTracker depthTracker
|
||||||
|
) throws LoadException {
|
||||||
|
if(!(o instanceof @Subst("a:o") String stringKey)) {
|
||||||
|
throw new LoadException("Value is not a String", depthTracker);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return Key.key(stringKey);
|
||||||
|
} catch(InvalidKeyException e) {
|
||||||
|
throw new LoadException("Can't load key: Invalid Format", e, depthTracker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.dfsek.terra.minestom.config;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.depth.DepthTracker;
|
||||||
|
import com.dfsek.tectonic.api.exception.LoadException;
|
||||||
|
import com.dfsek.tectonic.api.loader.ConfigLoader;
|
||||||
|
import com.dfsek.tectonic.api.loader.type.TypeLoader;
|
||||||
|
import net.kyori.adventure.key.InvalidKeyException;
|
||||||
|
import net.kyori.adventure.key.Key;
|
||||||
|
import net.kyori.adventure.util.RGBLike;
|
||||||
|
import net.minestom.server.color.Color;
|
||||||
|
import org.intellij.lang.annotations.Subst;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.AnnotatedType;
|
||||||
|
|
||||||
|
|
||||||
|
public class RGBLikeLoader implements TypeLoader<RGBLike> {
|
||||||
|
@Override
|
||||||
|
public RGBLike load(
|
||||||
|
@NotNull AnnotatedType annotatedType,
|
||||||
|
@NotNull Object o,
|
||||||
|
@NotNull ConfigLoader configLoader,
|
||||||
|
DepthTracker depthTracker
|
||||||
|
) throws LoadException {
|
||||||
|
if(!(o instanceof @Subst("a:o") Integer value)) {
|
||||||
|
throw new LoadException("Value is not an integer", depthTracker);
|
||||||
|
}
|
||||||
|
return new Color(value);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.dfsek.terra.minestom.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 net.kyori.adventure.key.Key;
|
||||||
|
import net.minestom.server.sound.SoundEvent;
|
||||||
|
|
||||||
|
|
||||||
|
public class SoundEventTemplate implements ObjectTemplate<SoundEvent> {
|
||||||
|
@Value("id")
|
||||||
|
@Default
|
||||||
|
private Key id = null;
|
||||||
|
|
||||||
|
@Value("distance-to-travel")
|
||||||
|
@Default
|
||||||
|
private Float distanceToTravel = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SoundEvent get() {
|
||||||
|
if(id == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
// distanceToTravel is specifically allowed to be null.
|
||||||
|
return SoundEvent.of(id, distanceToTravel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,140 @@
|
|||||||
|
package com.dfsek.terra.minestom.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 com.dfsek.terra.api.properties.Properties;
|
||||||
|
|
||||||
|
import net.kyori.adventure.util.RGBLike;
|
||||||
|
import net.minestom.server.sound.SoundEvent;
|
||||||
|
import net.minestom.server.world.biome.Biome.TemperatureModifier;
|
||||||
|
import net.minestom.server.world.biome.BiomeEffects;
|
||||||
|
import net.minestom.server.world.biome.BiomeEffects.GrassColorModifier;
|
||||||
|
|
||||||
|
|
||||||
|
public class VanillaBiomeProperties implements ConfigTemplate, Properties {
|
||||||
|
@Value("colors.grass")
|
||||||
|
@Default
|
||||||
|
private RGBLike grassColor = null;
|
||||||
|
|
||||||
|
@Value("colors.fog")
|
||||||
|
@Default
|
||||||
|
private RGBLike fogColor = null;
|
||||||
|
|
||||||
|
@Value("colors.water")
|
||||||
|
@Default
|
||||||
|
private RGBLike waterColor = null;
|
||||||
|
|
||||||
|
@Value("colors.water-fog")
|
||||||
|
@Default
|
||||||
|
private RGBLike waterFogColor = null;
|
||||||
|
|
||||||
|
@Value("colors.foliage")
|
||||||
|
@Default
|
||||||
|
private RGBLike foliageColor = null;
|
||||||
|
|
||||||
|
@Value("colors.sky")
|
||||||
|
@Default
|
||||||
|
private RGBLike skyColor = null;
|
||||||
|
|
||||||
|
@Value("colors.modifier")
|
||||||
|
@Default
|
||||||
|
private GrassColorModifier grassColorModifier = null;
|
||||||
|
|
||||||
|
@Value("particles")
|
||||||
|
@Default
|
||||||
|
private BiomeEffects.Particle particleConfig = null;
|
||||||
|
|
||||||
|
@Value("climate.precipitation")
|
||||||
|
@Default
|
||||||
|
private Boolean precipitation = null;
|
||||||
|
|
||||||
|
@Value("climate.temperature")
|
||||||
|
@Default
|
||||||
|
private Float temperature = null;
|
||||||
|
|
||||||
|
@Value("climate.temperature-modifier")
|
||||||
|
@Default
|
||||||
|
private TemperatureModifier temperatureModifier = null;
|
||||||
|
|
||||||
|
@Value("climate.downfall")
|
||||||
|
@Default
|
||||||
|
private Float downfall = null;
|
||||||
|
|
||||||
|
@Value("sound.loop-sound.sound")
|
||||||
|
@Default
|
||||||
|
private SoundEvent loopSound = null;
|
||||||
|
|
||||||
|
@Value("sound.mood-sound")
|
||||||
|
@Default
|
||||||
|
private BiomeEffects.MoodSound moodSound = null;
|
||||||
|
|
||||||
|
@Value("sound.additions-sound")
|
||||||
|
@Default
|
||||||
|
private BiomeEffects.AdditionsSound additionsSound = null;
|
||||||
|
|
||||||
|
// @Value("sound.music")
|
||||||
|
// @Default
|
||||||
|
// private MusicSound music = null;
|
||||||
|
|
||||||
|
public RGBLike getGrassColor() {
|
||||||
|
return grassColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RGBLike getFogColor() {
|
||||||
|
return fogColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RGBLike getWaterColor() {
|
||||||
|
return waterColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RGBLike getWaterFogColor() {
|
||||||
|
return waterFogColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RGBLike getFoliageColor() {
|
||||||
|
return foliageColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RGBLike getSkyColor() {
|
||||||
|
return skyColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GrassColorModifier getGrassColorModifier() {
|
||||||
|
return grassColorModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BiomeEffects.Particle getParticleConfig() {
|
||||||
|
return particleConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getPrecipitation() {
|
||||||
|
return precipitation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Float getTemperature() {
|
||||||
|
return temperature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TemperatureModifier getTemperatureModifier() {
|
||||||
|
return temperatureModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Float getDownfall() {
|
||||||
|
return downfall;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SoundEvent getLoopSound() {
|
||||||
|
return loopSound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BiomeEffects.MoodSound getMoodSound() {
|
||||||
|
return moodSound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BiomeEffects.AdditionsSound getAdditionsSound() {
|
||||||
|
return additionsSound;
|
||||||
|
}
|
||||||
|
}
|
@ -2,25 +2,25 @@ package com.dfsek.terra.minestom.world;
|
|||||||
|
|
||||||
import com.dfsek.terra.api.Platform;
|
import com.dfsek.terra.api.Platform;
|
||||||
import com.dfsek.terra.api.config.ConfigPack;
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
import com.dfsek.terra.api.world.biome.PlatformBiome;
|
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
|
import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
|
||||||
|
|
||||||
import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage;
|
import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage;
|
||||||
import com.dfsek.terra.api.world.chunk.generation.util.GeneratorWrapper;
|
import com.dfsek.terra.api.world.chunk.generation.util.GeneratorWrapper;
|
||||||
import com.dfsek.terra.minestom.biome.MinestomBiome;
|
import com.dfsek.terra.minestom.biome.MinestomCustomBiomeFactory;
|
||||||
|
import com.dfsek.terra.minestom.biome.MinestomCustomBiomePool;
|
||||||
|
import com.dfsek.terra.minestom.biome.NativeBiome;
|
||||||
import com.dfsek.terra.minestom.chunk.CachedChunk;
|
import com.dfsek.terra.minestom.chunk.CachedChunk;
|
||||||
import com.dfsek.terra.minestom.chunk.GeneratedChunkCache;
|
import com.dfsek.terra.minestom.chunk.GeneratedChunkCache;
|
||||||
|
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.coordinate.Point;
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.instance.generator.GenerationUnit;
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
import net.minestom.server.instance.generator.Generator;
|
import net.minestom.server.instance.generator.Generator;
|
||||||
import net.minestom.server.instance.generator.UnitModifier;
|
import net.minestom.server.instance.generator.UnitModifier;
|
||||||
import net.minestom.server.registry.DynamicRegistry;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
|
|
||||||
public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrapper {
|
public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrapper {
|
||||||
private final GeneratedChunkCache cache;
|
private final GeneratedChunkCache cache;
|
||||||
@ -28,14 +28,22 @@ public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrappe
|
|||||||
private final TerraMinestomWorld world;
|
private final TerraMinestomWorld world;
|
||||||
private final BiomeProvider biomeProvider;
|
private final BiomeProvider biomeProvider;
|
||||||
private ConfigPack pack;
|
private ConfigPack pack;
|
||||||
|
private final MinestomCustomBiomePool biomePool;
|
||||||
|
|
||||||
public MinestomChunkGeneratorWrapper(Platform platform, ChunkGenerator generator, TerraMinestomWorld world, ConfigPack pack) {
|
public MinestomChunkGeneratorWrapper(
|
||||||
|
Platform platform,
|
||||||
|
ChunkGenerator generator,
|
||||||
|
TerraMinestomWorld world,
|
||||||
|
ConfigPack pack,
|
||||||
|
MinestomCustomBiomePool biomePool
|
||||||
|
) {
|
||||||
this.generator = generator;
|
this.generator = generator;
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.pack = pack;
|
this.pack = pack;
|
||||||
|
this.biomePool = biomePool;
|
||||||
biomeProvider = pack.getBiomeProvider().caching(platform);
|
biomeProvider = pack.getBiomeProvider().caching(platform);
|
||||||
this.cache = new GeneratedChunkCache(world.getDimensionType(), generator, world, biomeProvider);
|
this.cache = new GeneratedChunkCache(world.getDimensionType(), generator, world, biomeProvider);
|
||||||
|
preloadBiomes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkGenerator getGenerator() {
|
public ChunkGenerator getGenerator() {
|
||||||
@ -53,30 +61,14 @@ public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrappe
|
|||||||
UnitModifier modifier = unit.modifier();
|
UnitModifier modifier = unit.modifier();
|
||||||
chunk.writeRelative(modifier);
|
chunk.writeRelative(modifier);
|
||||||
|
|
||||||
// for(int dx = 0; dx < 16; dx++) {
|
NativeBiome nativeBiome = biomePool.getBiome(biomeProvider.getBiome(blockX, 100, blockZ, world.getSeed()));
|
||||||
// for(int dz = 0; dz < 16; dz++) {
|
modifier.fillBiome(nativeBiome.registry());
|
||||||
// int globalX = dx + blockX;
|
|
||||||
// int globalZ = dz + blockZ;
|
|
||||||
// biomeProvider.getColumn(globalX, globalZ, world).forEach((y, biome) -> {
|
|
||||||
// MinestomBiome platformBiome = (MinestomBiome) biome.getPlatformBiome();
|
|
||||||
// modifier.setBiome(globalX, 0, globalZ, DynamicRegistry.Key.of("minecraft:the_void"));
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
unit.fork(setter -> {
|
unit.fork(setter -> {
|
||||||
MinestomProtoWorld protoWorld = new MinestomProtoWorld(cache, x, z, world, setter);
|
MinestomProtoWorld protoWorld = new MinestomProtoWorld(cache, x, z, world, setter);
|
||||||
|
|
||||||
var stages = world.getPack().getStages();
|
|
||||||
|
|
||||||
if(x==0 && z==0) {
|
|
||||||
System.out.println(stages);
|
|
||||||
System.out.println(protoWorld.getBlockState(-4, 73, -6).getAsString());
|
|
||||||
}
|
|
||||||
|
|
||||||
for(GenerationStage stage : world.getPack().getStages()) {
|
for(GenerationStage stage : world.getPack().getStages()) {
|
||||||
stage.populate(protoWorld);
|
stage.populate(protoWorld);
|
||||||
if(x==0 && z==0) System.out.println(protoWorld.getBlockState(-4, 73, -6).getAsString());
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -88,6 +80,15 @@ public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrappe
|
|||||||
public void setPack(ConfigPack pack) {
|
public void setPack(ConfigPack pack) {
|
||||||
this.pack = pack;
|
this.pack = pack;
|
||||||
this.generator = pack.getGeneratorProvider().newInstance(pack);
|
this.generator = pack.getGeneratorProvider().newInstance(pack);
|
||||||
|
this.biomePool.invalidate();
|
||||||
|
preloadBiomes();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void preloadBiomes() {
|
||||||
|
this.biomePool.preloadBiomes(world.getBiomeProvider().getBiomes());
|
||||||
|
for(Player player : MinecraftServer.getConnectionManager().getOnlinePlayers()) {
|
||||||
|
player.startConfigurationPhase();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void displayStats() {
|
public void displayStats() {
|
||||||
|
@ -16,6 +16,9 @@ import com.dfsek.terra.api.world.info.WorldProperties;
|
|||||||
import com.dfsek.terra.minestom.TerraMinestomPlatform;
|
import com.dfsek.terra.minestom.TerraMinestomPlatform;
|
||||||
import com.dfsek.terra.minestom.api.BlockEntityFactory;
|
import com.dfsek.terra.minestom.api.BlockEntityFactory;
|
||||||
import com.dfsek.terra.minestom.api.EntityFactory;
|
import com.dfsek.terra.minestom.api.EntityFactory;
|
||||||
|
import com.dfsek.terra.minestom.biome.BiomeFactory;
|
||||||
|
import com.dfsek.terra.minestom.biome.MinestomCustomBiomeFactory;
|
||||||
|
import com.dfsek.terra.minestom.biome.MinestomCustomBiomePool;
|
||||||
import com.dfsek.terra.minestom.block.MinestomBlockState;
|
import com.dfsek.terra.minestom.block.MinestomBlockState;
|
||||||
import com.dfsek.terra.minestom.entity.MinestomEntity;
|
import com.dfsek.terra.minestom.entity.MinestomEntity;
|
||||||
|
|
||||||
@ -44,7 +47,8 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties {
|
|||||||
ConfigPack pack,
|
ConfigPack pack,
|
||||||
long seed,
|
long seed,
|
||||||
EntityFactory entityFactory,
|
EntityFactory entityFactory,
|
||||||
BlockEntityFactory blockEntityFactory
|
BlockEntityFactory blockEntityFactory,
|
||||||
|
BiomeFactory factory
|
||||||
) {
|
) {
|
||||||
this.instance = instance;
|
this.instance = instance;
|
||||||
this.pack = pack;
|
this.pack = pack;
|
||||||
@ -53,7 +57,13 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties {
|
|||||||
this.dimensionType = MinecraftServer.getDimensionTypeRegistry().get(instance.getDimensionType());
|
this.dimensionType = MinecraftServer.getDimensionTypeRegistry().get(instance.getDimensionType());
|
||||||
this.blockEntityFactory = blockEntityFactory;
|
this.blockEntityFactory = blockEntityFactory;
|
||||||
|
|
||||||
this.wrapper = new MinestomChunkGeneratorWrapper(platform, pack.getGeneratorProvider().newInstance(pack), this, pack);
|
this.wrapper = new MinestomChunkGeneratorWrapper(
|
||||||
|
platform,
|
||||||
|
pack.getGeneratorProvider().newInstance(pack),
|
||||||
|
this,
|
||||||
|
pack,
|
||||||
|
new MinestomCustomBiomePool(pack, new MinestomCustomBiomeFactory())
|
||||||
|
);
|
||||||
this.entityFactory = entityFactory;
|
this.entityFactory = entityFactory;
|
||||||
|
|
||||||
instance.setGenerator(this.wrapper);
|
instance.setGenerator(this.wrapper);
|
||||||
|
@ -7,6 +7,8 @@ import com.dfsek.terra.api.registry.CheckedRegistry;
|
|||||||
import com.dfsek.terra.minestom.TerraMinestomPlatform;
|
import com.dfsek.terra.minestom.TerraMinestomPlatform;
|
||||||
import com.dfsek.terra.minestom.api.BlockEntityFactory;
|
import com.dfsek.terra.minestom.api.BlockEntityFactory;
|
||||||
import com.dfsek.terra.minestom.api.EntityFactory;
|
import com.dfsek.terra.minestom.api.EntityFactory;
|
||||||
|
import com.dfsek.terra.minestom.biome.BiomeFactory;
|
||||||
|
import com.dfsek.terra.minestom.biome.MinestomCustomBiomeFactory;
|
||||||
import com.dfsek.terra.minestom.block.DefaultBlockEntityFactory;
|
import com.dfsek.terra.minestom.block.DefaultBlockEntityFactory;
|
||||||
import com.dfsek.terra.minestom.entity.DefaultEntityFactory;
|
import com.dfsek.terra.minestom.entity.DefaultEntityFactory;
|
||||||
|
|
||||||
@ -24,6 +26,7 @@ public class TerraMinestomWorldBuilder {
|
|||||||
private long seed = new Random().nextLong();
|
private long seed = new Random().nextLong();
|
||||||
private EntityFactory entityFactory = new DefaultEntityFactory();
|
private EntityFactory entityFactory = new DefaultEntityFactory();
|
||||||
private BlockEntityFactory blockEntityFactory = new DefaultBlockEntityFactory();
|
private BlockEntityFactory blockEntityFactory = new DefaultBlockEntityFactory();
|
||||||
|
private BiomeFactory biomeFactory = new MinestomCustomBiomeFactory();
|
||||||
|
|
||||||
public TerraMinestomWorldBuilder(TerraMinestomPlatform platform, Instance instance) {
|
public TerraMinestomWorldBuilder(TerraMinestomPlatform platform, Instance instance) {
|
||||||
this.platform = platform;
|
this.platform = platform;
|
||||||
@ -65,7 +68,12 @@ public class TerraMinestomWorldBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TerraMinestomWorldBuilder biomeFactory(BiomeFactory factory) {
|
||||||
|
this.biomeFactory = factory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public TerraMinestomWorld attach() {
|
public TerraMinestomWorld attach() {
|
||||||
return new TerraMinestomWorld(platform, instance, pack, seed, entityFactory, blockEntityFactory);
|
return new TerraMinestomWorld(platform, instance, pack, seed, entityFactory, blockEntityFactory, biomeFactory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user