mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-06-18 06:40:55 +00:00
@@ -50,8 +50,9 @@ object Versions {
|
|||||||
object Bukkit {
|
object Bukkit {
|
||||||
const val paper = "1.18.2-R0.1-SNAPSHOT"
|
const val paper = "1.18.2-R0.1-SNAPSHOT"
|
||||||
const val paperLib = "1.0.5"
|
const val paperLib = "1.0.5"
|
||||||
const val minecraft = "1.19"
|
const val minecraft = "1.19.2"
|
||||||
const val reflectionRemapper = "0.1.0-SNAPSHOT"
|
const val reflectionRemapper = "0.1.0-SNAPSHOT"
|
||||||
|
const val paperDevBundle = "1.19.2-R0.1-SNAPSHOT"
|
||||||
}
|
}
|
||||||
|
|
||||||
object Sponge {
|
object Sponge {
|
||||||
|
|||||||
@@ -29,11 +29,11 @@ tasks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
runServer {
|
runServer {
|
||||||
minecraftVersion("1.19")
|
minecraftVersion(Versions.Bukkit.minecraft)
|
||||||
dependsOn(shadowJar)
|
dependsOn(shadowJar)
|
||||||
pluginJars(shadowJar.get().archiveFile)
|
pluginJars(shadowJar.get().archiveFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
addonDir(project.file("./target/server/paper/plugins/Terra/addons"), tasks.named("runServer").get())
|
addonDir(project.file("./run/plugins/Terra/addons"), tasks.named("runServer").get())
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ import ca.solostudios.strata.version.Version;
|
|||||||
|
|
||||||
import com.dfsek.terra.api.addon.BaseAddon;
|
import com.dfsek.terra.api.addon.BaseAddon;
|
||||||
import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent;
|
import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent;
|
||||||
|
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
|
||||||
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
||||||
import com.dfsek.terra.api.world.biome.Biome;
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
import com.dfsek.terra.bukkit.config.PreLoadCompatibilityOptions;
|
||||||
import com.dfsek.terra.bukkit.config.VanillaBiomeProperties;
|
import com.dfsek.terra.bukkit.config.VanillaBiomeProperties;
|
||||||
|
|
||||||
|
|
||||||
@@ -21,6 +23,12 @@ public class BukkitAddon implements BaseAddon {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
|
terraBukkitPlugin.getEventManager()
|
||||||
|
.getHandler(FunctionalEventHandler.class)
|
||||||
|
.register(this, ConfigPackPreLoadEvent.class)
|
||||||
|
.then(event -> event.getPack().getContext().put(event.loadTemplate(new PreLoadCompatibilityOptions())))
|
||||||
|
.global();
|
||||||
|
|
||||||
terraBukkitPlugin.getEventManager()
|
terraBukkitPlugin.getEventManager()
|
||||||
.getHandler(FunctionalEventHandler.class)
|
.getHandler(FunctionalEventHandler.class)
|
||||||
.register(this, ConfigurationLoadEvent.class)
|
.register(this, ConfigurationLoadEvent.class)
|
||||||
|
|||||||
+60
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.bukkit.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;
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("FieldMayBeFinal")
|
||||||
|
public class PreLoadCompatibilityOptions implements ConfigTemplate, Properties {
|
||||||
|
@Value("minecraft.use-vanilla-biomes")
|
||||||
|
@Default
|
||||||
|
private boolean vanillaBiomes = false;
|
||||||
|
|
||||||
|
@Value("minecraft.beard.enable")
|
||||||
|
@Default
|
||||||
|
private boolean beard = true;
|
||||||
|
|
||||||
|
@Value("minecraft.beard.threshold")
|
||||||
|
@Default
|
||||||
|
private double beardThreshold = 0.5;
|
||||||
|
|
||||||
|
@Value("minecraft.beard.air-threshold")
|
||||||
|
@Default
|
||||||
|
private double airThreshold = -0.5;
|
||||||
|
|
||||||
|
public boolean useVanillaBiomes() {
|
||||||
|
return vanillaBiomes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBeard() {
|
||||||
|
return beard;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getBeardThreshold() {
|
||||||
|
return beardThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getAirThreshold() {
|
||||||
|
return airThreshold;
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
-2
@@ -52,7 +52,12 @@ public class BukkitWorldHandle implements WorldHandle {
|
|||||||
@Override
|
@Override
|
||||||
public @NotNull EntityType getEntity(@NotNull String id) {
|
public @NotNull EntityType getEntity(@NotNull String id) {
|
||||||
if(!id.startsWith("minecraft:")) throw new IllegalArgumentException("Invalid entity identifier " + id);
|
if(!id.startsWith("minecraft:")) throw new IllegalArgumentException("Invalid entity identifier " + id);
|
||||||
return new BukkitEntityType(org.bukkit.entity.EntityType.valueOf(id.toUpperCase(Locale.ROOT).substring(10)));
|
String entityID = id.toUpperCase(Locale.ROOT).substring(10);
|
||||||
|
|
||||||
|
return new BukkitEntityType(switch(entityID) {
|
||||||
|
case "END_CRYSTAL" -> org.bukkit.entity.EntityType.ENDER_CRYSTAL;
|
||||||
|
case "ENDER_CRYSTAL" -> throw new IllegalArgumentException("Invalid entity identifier " + id); // make sure this issue can't happen the other way around.
|
||||||
|
default -> org.bukkit.entity.EntityType.valueOf(entityID);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(project(":platforms:bukkit:common"))
|
api(project(":platforms:bukkit:common"))
|
||||||
paperDevBundle("1.19-R0.1-SNAPSHOT")
|
paperDevBundle(Versions.Bukkit.paperDevBundle)
|
||||||
implementation("xyz.jpenilla", "reflection-remapper", "0.1.0-SNAPSHOT")
|
implementation("xyz.jpenilla", "reflection-remapper", "0.1.0-SNAPSHOT")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+50
-1
@@ -1,5 +1,11 @@
|
|||||||
package com.dfsek.terra.bukkit.nms.v1_19_R1;
|
package com.dfsek.terra.bukkit.nms.v1_19_R1;
|
||||||
|
|
||||||
|
import com.dfsek.terra.bukkit.config.PreLoadCompatibilityOptions;
|
||||||
|
|
||||||
|
import com.dfsek.terra.bukkit.world.BukkitWorldProperties;
|
||||||
|
|
||||||
|
import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
|
||||||
|
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
||||||
@@ -10,14 +16,21 @@ import net.minecraft.core.SectionPos;
|
|||||||
import net.minecraft.server.level.WorldGenRegion;
|
import net.minecraft.server.level.WorldGenRegion;
|
||||||
import net.minecraft.util.RandomSource;
|
import net.minecraft.util.RandomSource;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
import net.minecraft.world.level.LevelHeightAccessor;
|
import net.minecraft.world.level.LevelHeightAccessor;
|
||||||
import net.minecraft.world.level.NoiseColumn;
|
import net.minecraft.world.level.NoiseColumn;
|
||||||
import net.minecraft.world.level.StructureManager;
|
import net.minecraft.world.level.StructureManager;
|
||||||
import net.minecraft.world.level.WorldGenLevel;
|
import net.minecraft.world.level.WorldGenLevel;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
import net.minecraft.world.level.biome.BiomeManager;
|
import net.minecraft.world.level.biome.BiomeManager;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||||
|
import net.minecraft.world.level.levelgen.Beardifier;
|
||||||
|
import net.minecraft.world.level.levelgen.DensityFunction;
|
||||||
|
import net.minecraft.world.level.levelgen.DensityFunction.FunctionContext;
|
||||||
|
import net.minecraft.world.level.levelgen.DensityFunction.SinglePointContext;
|
||||||
import net.minecraft.world.level.levelgen.GenerationStep.Carving;
|
import net.minecraft.world.level.levelgen.GenerationStep.Carving;
|
||||||
import net.minecraft.world.level.levelgen.Heightmap.Types;
|
import net.minecraft.world.level.levelgen.Heightmap.Types;
|
||||||
import net.minecraft.world.level.levelgen.RandomState;
|
import net.minecraft.world.level.levelgen.RandomState;
|
||||||
@@ -103,7 +116,43 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
|||||||
public @NotNull CompletableFuture<ChunkAccess> fillFromNoise(@NotNull Executor executor, @NotNull Blender blender,
|
public @NotNull CompletableFuture<ChunkAccess> fillFromNoise(@NotNull Executor executor, @NotNull Blender blender,
|
||||||
@NotNull RandomState noiseConfig,
|
@NotNull RandomState noiseConfig,
|
||||||
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk) {
|
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk) {
|
||||||
return vanilla.fillFromNoise(executor, blender, noiseConfig, structureAccessor, chunk);
|
return vanilla.fillFromNoise(executor, blender, noiseConfig, structureAccessor, chunk)
|
||||||
|
.thenApply(c -> {
|
||||||
|
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
|
||||||
|
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||||
|
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
|
||||||
|
if(compatibilityOptions.isBeard()) {
|
||||||
|
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()), biomeProvider, compatibilityOptions);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void beard(StructureManager structureAccessor, ChunkAccess chunk, WorldProperties world, BiomeProvider biomeProvider,
|
||||||
|
PreLoadCompatibilityOptions compatibilityOptions) {
|
||||||
|
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;
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
for(int z = 0; z < 16; z++) {
|
||||||
|
int depth = 0;
|
||||||
|
for(int y = world.getMaxHeight(); y >= world.getMinHeight(); y--) {
|
||||||
|
double noise = structureWeightSampler.compute(new SinglePointContext(x + xi, y, z + zi));
|
||||||
|
if(noise > threshold) {
|
||||||
|
chunk.setBlockState(new BlockPos(x, y, z), ((CraftBlockData) ((BukkitBlockState) delegate
|
||||||
|
.getPalette(x + xi, y, z + zi, world, biomeProvider)
|
||||||
|
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
|
||||||
|
depth++;
|
||||||
|
} else if(noise < airThreshold) {
|
||||||
|
chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), false);
|
||||||
|
} else {
|
||||||
|
depth = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+11
@@ -1,14 +1,18 @@
|
|||||||
package com.dfsek.terra.bukkit.nms.v1_19_R1;
|
package com.dfsek.terra.bukkit.nms.v1_19_R1;
|
||||||
|
|
||||||
import net.minecraft.core.MappedRegistry;
|
import net.minecraft.core.MappedRegistry;
|
||||||
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
|
import net.minecraft.world.level.StructureManager;
|
||||||
import xyz.jpenilla.reflectionremapper.ReflectionRemapper;
|
import xyz.jpenilla.reflectionremapper.ReflectionRemapper;
|
||||||
import xyz.jpenilla.reflectionremapper.proxy.ReflectionProxyFactory;
|
import xyz.jpenilla.reflectionremapper.proxy.ReflectionProxyFactory;
|
||||||
|
import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldGetter;
|
||||||
import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldSetter;
|
import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldSetter;
|
||||||
import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies;
|
import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies;
|
||||||
|
|
||||||
|
|
||||||
public class Reflection {
|
public class Reflection {
|
||||||
public static final MappedRegistryProxy MAPPED_REGISTRY;
|
public static final MappedRegistryProxy MAPPED_REGISTRY;
|
||||||
|
public static final StructureManagerProxy STRUCTURE_MANAGER;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar();
|
ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar();
|
||||||
@@ -16,6 +20,7 @@ public class Reflection {
|
|||||||
Reflection.class.getClassLoader());
|
Reflection.class.getClassLoader());
|
||||||
|
|
||||||
MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class);
|
MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class);
|
||||||
|
STRUCTURE_MANAGER = reflectionProxyFactory.reflectionProxy(StructureManagerProxy.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -24,4 +29,10 @@ public class Reflection {
|
|||||||
@FieldSetter("frozen")
|
@FieldSetter("frozen")
|
||||||
void setFrozen(MappedRegistry<?> instance, boolean frozen);
|
void setFrozen(MappedRegistry<?> instance, boolean frozen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Proxies(StructureManager.class)
|
||||||
|
public interface StructureManagerProxy {
|
||||||
|
@FieldGetter("level")
|
||||||
|
LevelAccessor getLevel(StructureManager instance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user