Compare commits

...

5 Commits

Author SHA1 Message Date
dfsek eca46a7c64 start working on mixins 2021-06-05 00:49:38 -07:00
dfsek 74fdf9a18e start working on internal stuff 2021-06-02 15:21:03 -07:00
dfsek c0f1ccb66a initialize earlier 2021-06-02 10:39:36 -07:00
dfsek 44410323af config loading w/o errors 2021-06-02 10:26:55 -07:00
dfsek aaf32709b4 set up sponge api8 project 2021-06-02 09:45:11 -07:00
16 changed files with 578 additions and 47 deletions
+22 -1
View File
@@ -3,6 +3,7 @@ import com.dfsek.terra.configureCommon
plugins {
java
id("org.spongepowered.plugin").version("0.9.0")
id("org.spongepowered.gradle.vanilla").version("0.2")
}
configureCommon()
@@ -15,7 +16,11 @@ repositories {
}
dependencies {
"compileOnly"("org.spongepowered:spongeapi:7.2.0")
"compileOnly"("org.spongepowered:spongeapi:8.0.0-SNAPSHOT")
"annotationProcessor"("org.spongepowered:mixin:0.8.2:processor")
"compileOnly"("org.spongepowered:mixin:0.8.2")
"shadedApi"(project(":common"))
"shadedImplementation"("org.yaml:snakeyaml:1.27")
"shadedImplementation"("com.googlecode.json-simple:json-simple:1.1.1")
@@ -25,4 +30,20 @@ sponge {
plugin {
id = "terra"
}
}
minecraft {
version("1.16.5")
runs {
server()
client()
}
}
tasks.named<Jar>("jar") {
manifest {
attributes(
mapOf("MixinConfigs" to "terra.mixins.json")
)
}
}
@@ -1,15 +0,0 @@
package com.dfsek.terra.sponge;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.sponge.world.block.data.SpongeBlockData;
import org.spongepowered.api.block.BlockState;
public final class SpongeAdapter {
public static BlockData adapt(BlockState state) {
return new SpongeBlockData(state);
}
public static BlockState adapt(BlockData data) {
return ((SpongeBlockData) data).getHandle();
}
}
@@ -3,9 +3,9 @@ package com.dfsek.terra.sponge;
import com.dfsek.terra.api.util.logging.Logger;
public class SpongeLogger implements Logger {
private final org.slf4j.Logger logger;
private final org.apache.logging.log4j.Logger logger;
public SpongeLogger(org.slf4j.Logger logger) {
public SpongeLogger(org.apache.logging.log4j.Logger logger) {
this.logger = logger;
}
@@ -3,77 +3,124 @@ package com.dfsek.terra.sponge;
import com.dfsek.tectonic.loading.TypeRegistry;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.addons.TerraAddon;
import com.dfsek.terra.api.addons.annotations.Addon;
import com.dfsek.terra.api.addons.annotations.Author;
import com.dfsek.terra.api.addons.annotations.Version;
import com.dfsek.terra.api.event.EventListener;
import com.dfsek.terra.api.event.EventManager;
import com.dfsek.terra.api.event.TerraEventManager;
import com.dfsek.terra.api.event.annotations.Global;
import com.dfsek.terra.api.event.events.config.ConfigPackPreLoadEvent;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.handle.ItemHandle;
import com.dfsek.terra.api.platform.handle.WorldHandle;
import com.dfsek.terra.api.platform.world.Biome;
import com.dfsek.terra.api.platform.world.Tree;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.registry.LockedRegistry;
import com.dfsek.terra.api.util.generic.pair.Pair;
import com.dfsek.terra.api.util.logging.DebugLogger;
import com.dfsek.terra.config.GenericLoaders;
import com.dfsek.terra.config.PluginConfig;
import com.dfsek.terra.config.lang.Language;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.profiler.Profiler;
import com.dfsek.terra.profiler.ProfilerImpl;
import com.dfsek.terra.registry.exception.DuplicateEntryException;
import com.dfsek.terra.registry.master.AddonRegistry;
import com.dfsek.terra.registry.master.ConfigRegistry;
import com.dfsek.terra.sponge.world.SpongeWorldHandle;
import com.dfsek.terra.sponge.handle.SpongeItemHandle;
import com.dfsek.terra.sponge.handle.SpongeWorldHandle;
import com.dfsek.terra.sponge.intern.util.SpongeUtil;
import com.dfsek.terra.sponge.world.SpongeTree;
import com.dfsek.terra.world.TerraWorld;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.spongepowered.api.config.ConfigDir;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.dimension.DimensionType;
import org.spongepowered.api.Server;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.game.state.GameStartedServerEvent;
import org.spongepowered.api.plugin.Plugin;
import org.spongepowered.api.event.lifecycle.StartedEngineEvent;
import org.spongepowered.api.event.lifecycle.StartingEngineEvent;
import org.spongepowered.api.registry.Registry;
import org.spongepowered.api.world.biome.Biomes;
import org.spongepowered.api.world.server.ServerWorld;
import org.spongepowered.plugin.PluginContainer;
import org.spongepowered.plugin.jvm.Plugin;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
@Plugin(id = "terra", name = "Terra-Sponge", version = "", description = "Terra")
@Plugin("terra")
public class TerraSpongePlugin implements TerraPlugin {
private final ConfigRegistry configRegistry = new ConfigRegistry();
private final CheckedRegistry<ConfigPack> packCheckedRegistry = new CheckedRegistry<>(configRegistry);
private final PluginConfig config = new PluginConfig();
private final AddonRegistry addonRegistry = new AddonRegistry(this);
private final LockedRegistry<TerraAddon> addonLockedRegistry = new LockedRegistry<>(addonRegistry);
private final SpongeWorldHandle spongeWorldHandle = new SpongeWorldHandle();
private final EventManager eventManager = new TerraEventManager(this);
private final AddonRegistry addonRegistry;
private final LockedRegistry<TerraAddon> addonLockedRegistry;
private static TerraSpongePlugin INSTANCE;
private final Map<DimensionType, Pair<ServerWorld, TerraWorld>> worldMap = new HashMap<>();
private final PluginContainer plugin;
private final GenericLoaders loaders = new GenericLoaders(this);
private final WorldHandle worldHandle = new SpongeWorldHandle();
private final Profiler profiler = new ProfilerImpl();
@Inject
@ConfigDir(sharedRoot = false)
private Path privateConfigDir;
@Inject
private Logger logger;
public TerraSpongePlugin(PluginContainer plugin) {
this.plugin = plugin;
this.addonRegistry = new AddonRegistry(new SpongeAddon(this), this);
this.addonLockedRegistry = new LockedRegistry<>(addonRegistry);
INSTANCE = this;
}
public static TerraSpongePlugin getInstance() {
return INSTANCE;
}
@Listener
public void initialize(GameStartedServerEvent event) {
public void initialize(StartingEngineEvent<Server> event) {
plugin.logger().info("Loading Terra...");
addonRegistry.loadAll();
configRegistry.loadAll(this);
}
@Override
public void register(TypeRegistry registry) {
loaders.register(registry);
registry.registerLoader(BlockData.class, (t, o, l) -> worldHandle.createBlockData((String) o))
.registerLoader(Biome.class, (t, o, l) -> SpongeUtil.BIOME_FIXER.translate((String) o));
}
@Override
public WorldHandle getWorldHandle() {
return spongeWorldHandle;
return worldHandle;
}
@Override
public TerraWorld getWorld(World world) {
return null;
return getWorld(((LevelReader) world).dimensionType());
}
public TerraWorld getWorld(DimensionType type) {
TerraWorld world = worldMap.get(type).getRight();
if(world == null) throw new IllegalArgumentException("No world exists with dimension type " + type);
return world;
}
@Override
public com.dfsek.terra.api.util.logging.Logger logger() {
return new SpongeLogger(logger);
return new SpongeLogger(plugin.logger());
}
@Override
@@ -83,7 +130,7 @@ public class TerraSpongePlugin implements TerraPlugin {
@Override
public File getDataFolder() {
return privateConfigDir.toFile();
return Sponge.configManager().pluginConfig(plugin).directory().toFile();
}
@Override
@@ -117,7 +164,7 @@ public class TerraSpongePlugin implements TerraPlugin {
@Override
public ItemHandle getItemHandle() {
return null;
return new SpongeItemHandle();
}
@Override
@@ -132,7 +179,7 @@ public class TerraSpongePlugin implements TerraPlugin {
@Override
public DebugLogger getDebugLogger() {
return null;
return new DebugLogger(logger());
}
@Override
@@ -142,6 +189,59 @@ public class TerraSpongePlugin implements TerraPlugin {
@Override
public Profiler getProfiler() {
return null;
return profiler;
}
public Map<DimensionType,Pair<ServerWorld, TerraWorld>> getWorldMap() {
return worldMap;
}
@Addon("Terra-Sponge")
@Author("Terra")
@Version("1.0.0")
private static final class SpongeAddon extends TerraAddon implements EventListener {
private final TerraPlugin main;
private SpongeAddon(TerraPlugin main) {
this.main = main;
}
@Override
public void initialize() {
main.getEventManager().registerListener(this, this);
}
@Global
public void onPackLoad(ConfigPackPreLoadEvent event) {
CheckedRegistry<Tree> treeRegistry = event.getPack().getTreeRegistry();
injectTree(treeRegistry, "BROWN_MUSHROOM", new SpongeTree());
injectTree(treeRegistry, "RED_MUSHROOM", new SpongeTree());
injectTree(treeRegistry, "JUNGLE", new SpongeTree());
injectTree(treeRegistry, "JUNGLE_COCOA", new SpongeTree());
injectTree(treeRegistry, "LARGE_OAK", new SpongeTree());
injectTree(treeRegistry, "LARGE_SPRUCE", new SpongeTree());
injectTree(treeRegistry, "SMALL_JUNGLE", new SpongeTree());
injectTree(treeRegistry, "SWAMP_OAK", new SpongeTree());
injectTree(treeRegistry, "TALL_BIRCH", new SpongeTree());
injectTree(treeRegistry, "ACACIA", new SpongeTree());
injectTree(treeRegistry, "BIRCH", new SpongeTree());
injectTree(treeRegistry, "DARK_OAK", new SpongeTree());
injectTree(treeRegistry, "OAK", new SpongeTree());
injectTree(treeRegistry, "CHORUS_PLANT", new SpongeTree());
injectTree(treeRegistry, "SPRUCE", new SpongeTree());
injectTree(treeRegistry, "JUNGLE_BUSH", new SpongeTree());
injectTree(treeRegistry, "MEGA_SPRUCE", new SpongeTree());
injectTree(treeRegistry, "CRIMSON_FUNGUS", new SpongeTree());
injectTree(treeRegistry, "WARPED_FUNGUS", new SpongeTree());
}
private void injectTree(CheckedRegistry<Tree> registry, String id, Tree tree) {
try {
registry.add(id, tree);
} catch(DuplicateEntryException e) {
e.printStackTrace();
}
}
}
}
@@ -0,0 +1,24 @@
package com.dfsek.terra.sponge.handle;
import com.dfsek.terra.api.platform.handle.ItemHandle;
import com.dfsek.terra.api.platform.inventory.Item;
import com.dfsek.terra.api.platform.inventory.item.Enchantment;
import java.util.Set;
public class SpongeItemHandle implements ItemHandle {
@Override
public Item createItem(String data) {
return null;
}
@Override
public Enchantment getEnchantment(String id) {
return null;
}
@Override
public Set<Enchantment> getEnchantments() {
return null;
}
}
@@ -1,16 +1,16 @@
package com.dfsek.terra.sponge.world;
package com.dfsek.terra.sponge.handle;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.entity.EntityType;
import com.dfsek.terra.api.platform.handle.WorldHandle;
import com.dfsek.terra.sponge.SpongeAdapter;
import com.dfsek.terra.sponge.intern.util.SpongeAdapter;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.block.BlockState;
public class SpongeWorldHandle implements WorldHandle {
@Override
public BlockData createBlockData(String data) {
return SpongeAdapter.adapt(Sponge.getRegistry().getType(BlockState.class, data).orElseThrow(() -> new IllegalArgumentException("Invalid block data \"" + data + "\"")));
return SpongeAdapter.adapt(BlockState.fromString(data));
}
@Override
@@ -0,0 +1,200 @@
package com.dfsek.terra.sponge.intern;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.api.platform.world.generator.ChunkData;
import com.dfsek.terra.api.platform.world.generator.GeneratorWrapper;
import com.dfsek.terra.api.util.FastRandom;
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
import com.dfsek.terra.api.world.locate.AsyncStructureFinder;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.sponge.TerraSpongePlugin;
import com.dfsek.terra.sponge.intern.util.SpongeAdapter;
import com.dfsek.terra.world.TerraWorld;
import com.dfsek.terra.world.generation.generators.DefaultChunkGenerator3D;
import com.dfsek.terra.world.generation.math.samplers.Sampler;
import com.dfsek.terra.world.population.items.TerraStructure;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.jafama.FastMath;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.NaturalSpawner;
import net.minecraft.world.level.NoiseColumn;
import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.biome.Biome;
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.ChunkGenerator;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.world.level.levelgen.GenerationStep;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.StructureSettings;
import net.minecraft.world.level.levelgen.WorldgenRandom;
import net.minecraft.world.level.levelgen.feature.StructureFeature;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.api.world.biome.provider.BiomeProvider;
import org.spongepowered.api.world.generation.config.structure.StructureGenerationConfig;
import org.spongepowered.api.world.server.ServerWorld;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class SpongeChunkGeneratorWrapper extends ChunkGenerator implements GeneratorWrapper {
private final long seed;
private final DefaultChunkGenerator3D delegate;
private final TerraBiomeSource biomeSource;
public static final Codec<ConfigPack> PACK_CODEC = (RecordCodecBuilder.create(config -> config.group(
Codec.STRING.fieldOf("pack").forGetter(pack -> pack.getTemplate().getID())
).apply(config, config.stable(TerraSpongePlugin.getInstance().getConfigRegistry()::get))));
public static final Codec<SpongeChunkGeneratorWrapper> CODEC = RecordCodecBuilder.create(instance -> instance.group(
TerraBiomeSource.CODEC.fieldOf("biome_source").forGetter(generator -> generator.biomeSource),
Codec.LONG.fieldOf("seed").stable().forGetter(generator -> generator.seed),
PACK_CODEC.fieldOf("pack").stable().forGetter(generator -> generator.pack))
.apply(instance, instance.stable(SpongeChunkGeneratorWrapper::new)));
private final ConfigPack pack;
public ConfigPack getPack() {
return pack;
}
private DimensionType dimensionType;
public SpongeChunkGeneratorWrapper(TerraBiomeSource biomeSource, long seed, ConfigPack configPack) {
super(biomeSource, new StructureSettings(configPack.getTemplate().vanillaStructures()));
this.pack = configPack;
this.delegate = new DefaultChunkGenerator3D(pack, TerraSpongePlugin.getInstance());
delegate.getMain().logger().info("Loading world with config pack " + pack.getTemplate().getID());
this.biomeSource = biomeSource;
this.seed = seed;
}
@Override
protected @NotNull Codec<? extends ChunkGenerator> codec() {
return CODEC;
}
@Override
public @NotNull ChunkGenerator withSeed(long seed) {
return new SpongeChunkGeneratorWrapper((TerraBiomeSource) this.biomeSource.withSeed(seed), seed, pack);
}
@Override
public void buildSurfaceAndBedrock(WorldGenRegion worldGenRegion, ChunkAccess chunkAccess) {
}
@Nullable
@Override
public BlockPos findNearestMapFeature(ServerLevel world, StructureFeature<?> feature, BlockPos center, int param3, boolean param4) {
if(!pack.getTemplate().disableStructures()) {
String name = Objects.requireNonNull(Registry.STRUCTURE_FEATURE.getKey(feature)).toString();
TerraWorld terraWorld = TerraSpongePlugin.getInstance().getWorld((World) world);
TerraStructure located = pack.getStructure(pack.getTemplate().getLocatable().get(name));
if(located != null) {
CompletableFuture<BlockPos> result = new CompletableFuture<>();
AsyncStructureFinder finder = new AsyncStructureFinder(terraWorld.getBiomeProvider(), located, SpongeAdapter.adapt(center).toLocation((World) world), 0, 500, location -> {
result.complete(SpongeAdapter.adapt(location));
}, TerraSpongePlugin.getInstance());
finder.run(); // Do this synchronously.
try {
return result.get();
} catch(InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}
return super.findNearestMapFeature(world, feature, center, param3, param4);
}
@Override
public boolean hasStronghold(@NotNull ChunkPos p_235952_1_) {
if(pack.getTemplate().vanillaStructures()) return super.hasStronghold(p_235952_1_);
return false;
}
@Override
public void createStructures(RegistryAccess param0, StructureFeatureManager param1, ChunkAccess param2, StructureManager param3, long param4) {
if(pack.getTemplate().vanillaStructures()) super.createStructures(param0, param1, param2, param3, param4);
}
@Override
public void applyCarvers(long param0, BiomeManager param1, ChunkAccess param2, GenerationStep.Carving param3) {
if(pack.getTemplate().vanillaCaves()) super.applyCarvers(param0, param1, param2, param3);
}
@Override
public void fillFromNoise(@NotNull LevelAccessor world, @NotNull StructureFeatureManager p_230352_2_, @NotNull ChunkAccess chunk) {
delegate.generateChunkData((World) world, new FastRandom(), chunk.getPos().x, chunk.getPos().z, (ChunkData) chunk);
}
@Override
public int getBaseHeight(int x, int z, Heightmap.@NotNull Types p_222529_3_) {
TerraWorld world = TerraSpongePlugin.getInstance().getWorld(dimensionType);
Sampler sampler = world.getConfig().getSamplerCache().getChunk(FastMath.floorDiv(x, 16), FastMath.floorDiv(z, 16));
int cx = FastMath.floorMod(x, 16);
int cz = FastMath.floorMod(z, 16);
int height = world.getWorld().getMaxHeight();
while(height >= 0 && sampler.sample(cx, height - 1, cz) < 0) height--;
return height;
}
@Override
public @NotNull BlockGetter getBaseColumn(int x, int z) {
TerraWorld world = TerraSpongePlugin.getInstance().getWorld(dimensionType);
int height = getBaseHeight(x, z, Heightmap.Types.WORLD_SURFACE);
BlockState[] array = new BlockState[256];
for(int y = 255; y >= 0; y--) {
if(y > height) {
if(y > ((UserDefinedBiome) world.getBiomeProvider().getBiome(x, z)).getConfig().getSeaLevel()) {
array[y] = Blocks.AIR.defaultBlockState();
} else {
array[y] = Blocks.WATER.defaultBlockState();
}
} else {
array[y] = Blocks.STONE.defaultBlockState();
}
}
return new NoiseColumn(array);
}
@Override
public void spawnOriginalMobs(WorldGenRegion region) {
if(pack.getTemplate().vanillaMobs()) {
int cx = region.getCenterX();
int cy = region.getCenterZ();
Biome biome = region.getBiome((new ChunkPos(cx, cy)).getWorldPosition());
WorldgenRandom chunkRandom = new WorldgenRandom();
chunkRandom.setDecorationSeed(region.getSeed(), cx << 4, cy << 4);
NaturalSpawner.spawnMobsForChunkGeneration(region, biome, cx, cy, chunkRandom);
}
}
@Override
public TerraChunkGenerator getHandle() {
return delegate;
}
public void setDimensionType(DimensionType dimensionType) {
this.dimensionType = dimensionType;
}
}
@@ -0,0 +1,63 @@
package com.dfsek.terra.sponge.intern;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.config.pack.WorldConfig;
import com.dfsek.terra.sponge.TerraSpongePlugin;
import com.dfsek.terra.sponge.intern.util.SpongeUtil;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.Registry;
import net.minecraft.resources.RegistryLookupCodec;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeSource;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
public class TerraBiomeSource extends BiomeSource {
public static final Codec<ConfigPack> PACK_CODEC = (RecordCodecBuilder.create(config -> config.group(
Codec.STRING.fieldOf("pack").forGetter(pack -> pack.getTemplate().getID())
).apply(config, config.stable(TerraSpongePlugin.getInstance().getConfigRegistry()::get))));
public static final Codec<TerraBiomeSource> CODEC = RecordCodecBuilder.create(instance -> instance.group(
RegistryLookupCodec.create(Registry.BIOME_REGISTRY).forGetter(source -> source.biomeRegistry),
Codec.LONG.fieldOf("seed").stable().forGetter(source -> source.seed),
PACK_CODEC.fieldOf("pack").stable().forGetter(source -> source.pack))
.apply(instance, instance.stable(TerraBiomeSource::new)));
private final Registry<Biome> biomeRegistry;
private final long seed;
private final BiomeProvider grid;
private final ConfigPack pack;
public TerraBiomeSource(Registry<Biome> biomes, long seed, ConfigPack pack) {
super(biomes.stream().collect(Collectors.toList()));
this.biomeRegistry = biomes;
this.seed = seed;
this.grid = pack.getBiomeProviderBuilder().build(seed);
this.pack = pack;
}
@Override
protected @NotNull Codec<TerraBiomeSource> codec() {
return CODEC;
}
@Override
public BiomeSource withSeed(long seed) {
return new TerraBiomeSource(this.biomeRegistry, seed, pack);
}
@Override
public @NotNull Biome getNoiseBiome(int biomeX, int biomeY, int biomeZ) {
UserDefinedBiome biome = (UserDefinedBiome) grid.getBiome(biomeX << 2, biomeZ << 2);
return Objects.requireNonNull(biomeRegistry.get(new ResourceLocation("terra", SpongeUtil.createBiomeID(pack, biome.getID()))));
}
}
@@ -0,0 +1,35 @@
package com.dfsek.terra.sponge.intern.mixin;
import com.dfsek.terra.api.util.generic.pair.Pair;
import com.dfsek.terra.sponge.TerraSpongePlugin;
import com.dfsek.terra.sponge.intern.SpongeChunkGeneratorWrapper;
import com.dfsek.terra.world.TerraWorld;
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.dimension.DimensionType;
import org.spongepowered.api.world.server.ServerWorld;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(ServerLevel.class)
public abstract class ServerLevelMixin {
@Shadow
@Final
private ServerChunkCache chunkSource;
@Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;updateSkyBrightness()V"))
public void injectConstructor(Level level) {
if(chunkSource.getGenerator() instanceof SpongeChunkGeneratorWrapper) {
SpongeChunkGeneratorWrapper chunkGeneratorWrapper = (SpongeChunkGeneratorWrapper) chunkSource.getGenerator();
DimensionType dimensionType = ((Level) (Object) this).dimensionType();
TerraSpongePlugin.getInstance().getWorldMap().put(dimensionType, Pair.of((ServerWorld) this, new TerraWorld((com.dfsek.terra.api.platform.world.World) this, chunkGeneratorWrapper.getPack(), TerraSpongePlugin.getInstance())));
chunkGeneratorWrapper.setDimensionType(dimensionType);
TerraSpongePlugin.getInstance().logger().info("Registered world " + this + " to dimension type " + dimensionType);
}
((Level) (Object) this).updateSkyBrightness();
}
}
@@ -0,0 +1,6 @@
/**
* Stuff that accesses the internal server.
* <p>
* Should be replaced with API stuff when API is complete.
*/
package com.dfsek.terra.sponge.intern;
@@ -0,0 +1,21 @@
package com.dfsek.terra.sponge.intern.util;
import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.sponge.world.block.data.SpongeBlockData;
import net.minecraft.core.BlockPos;
import org.spongepowered.api.block.BlockState;
public final class SpongeAdapter {
public static Vector3 adapt(BlockPos pos) {
return new Vector3(pos.getX(), pos.getY(), pos.getZ());
}
public static BlockPos adapt(Vector3 vec) {
return new BlockPos(vec.getBlockX(), vec.getBlockY(), vec.getBlockZ());
}
public static BlockData adapt(BlockState state) {
return new SpongeBlockData(state);
}
}
@@ -0,0 +1,21 @@
package com.dfsek.terra.sponge.intern.util;
import com.dfsek.terra.api.transform.Transformer;
import com.dfsek.terra.api.transform.Validator;
import com.dfsek.terra.config.pack.ConfigPack;
import net.minecraft.data.BuiltinRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.biome.Biome;
import java.util.Locale;
public final class SpongeUtil {
public static String createBiomeID(ConfigPack pack, String biomeID) {
return pack.getTemplate().getID().toLowerCase() + "/" + biomeID.toLowerCase(Locale.ROOT);
}
public static final Transformer<String, Biome> BIOME_FIXER = new Transformer.Builder<String, Biome>()
.addTransform(id -> BuiltinRegistries.BIOME.get(ResourceLocation.tryParse(id)), Validator.notNull())
.addTransform(id -> BuiltinRegistries.BIOME.get(ResourceLocation.tryParse("minecraft:" + id.toLowerCase())), Validator.notNull()).build();
}
@@ -0,0 +1,19 @@
package com.dfsek.terra.sponge.world;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.platform.world.Tree;
import com.dfsek.terra.api.util.collections.MaterialSet;
import java.util.Random;
public class SpongeTree implements Tree {
@Override
public boolean plant(Location l, Random r) {
return false;
}
@Override
public MaterialSet getSpawnable() {
return MaterialSet.empty();
}
}
@@ -0,0 +1 @@
MixinConfigs: terra.mixins.json
@@ -0,0 +1,18 @@
{
"plugins": [
{
"loader": "java_plain",
"id": "terra",
"name": "Terra",
"version": "@VERSION@",
"main-class": "com.dfsek.terra.sponge.TerraSpongePlugin",
"description": "@DESCRIPTION@",
"dependencies": [
{
"id": "spongeapi",
"version": "8.0.0"
}
]
}
]
}
@@ -0,0 +1,17 @@
{
"required": true,
"package": "com.dfsek.terra.sponge.intern.mixin",
"compatibilityLevel": "JAVA_8",
"refmap": "terra-refmap.json",
"mixins": [
"ServerLevelMixin"
],
"client": [
],
"server": [
],
"injectors": {
"defaultRequire": 1
},
"minVersion": "0.8"
}