diff --git a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/listeners/PaperListener.java b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/listeners/PaperListener.java index 5423ea7dc..2e98877f8 100644 --- a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/listeners/PaperListener.java +++ b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/listeners/PaperListener.java @@ -19,7 +19,6 @@ public class PaperListener implements Listener { @EventHandler public void onStructureLocate(StructureLocateEvent e) { if(!BukkitAdapter.adapt(e.getWorld()).isTerraWorld()) return; - e.setResult(null); // Assume no result. String name = "minecraft:" + e.getType().getName(); main.getDebugLogger().info("Overriding structure location for \"" + name + "\""); TerraWorld tw = main.getWorld(BukkitAdapter.adapt(e.getWorld())); @@ -32,10 +31,8 @@ public class PaperListener implements Listener { }, main); finder.run(); // Do this synchronously. } else { - main.logger().warning("No overrides are defined for \"" + name + "\""); + e.setResult(e.getOrigin()); + main.logger().warning("No overrides are defined for \"" + name + "\". Locating this structure will NOT work properly!"); } - } - - } diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/generation/FabricChunkGeneratorWrapper.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/generation/FabricChunkGeneratorWrapper.java index 78ab7f8a2..b4efa496e 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/generation/FabricChunkGeneratorWrapper.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/generation/FabricChunkGeneratorWrapper.java @@ -109,11 +109,6 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Gener return null; } - @Override - public void generateFeatures(ChunkRegion region, StructureAccessor accessor) { - super.generateFeatures(region, accessor); - } - @Override public void populateNoise(WorldAccess world, StructureAccessor accessor, Chunk chunk) { delegate.generateChunkData((World) world, new FastRandom(), chunk.getPos().x, chunk.getPos().z, (ChunkData) chunk); @@ -121,16 +116,15 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Gener @Override public void carve(long seed, BiomeAccess access, Chunk chunk, GenerationStep.Carver carver) { - // No caves + if(pack.getTemplate().vanillaCaves()) super.carve(seed, access, chunk, carver); } @Override public void setStructureStarts(DynamicRegistryManager dynamicRegistryManager, StructureAccessor structureAccessor, Chunk chunk, StructureManager structureManager, long worldSeed) { - + if(pack.getTemplate().vanillaStructures()) + super.setStructureStarts(dynamicRegistryManager, structureAccessor, chunk, structureManager, worldSeed); } - - @Override public boolean isStrongholdStartingChunk(ChunkPos chunkPos) { return false; diff --git a/platforms/forge/build.gradle.kts b/platforms/forge/build.gradle.kts index 2bfb7ad0e..682981977 100644 --- a/platforms/forge/build.gradle.kts +++ b/platforms/forge/build.gradle.kts @@ -1,6 +1,6 @@ import com.dfsek.terra.configureCommon +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import net.minecraftforge.gradle.common.util.RunConfig -import net.minecraftforge.gradle.mcp.task.GenerateSRG import net.minecraftforge.gradle.userdev.UserDevExtension import net.minecraftforge.gradle.userdev.tasks.RenameJarInPlace @@ -55,11 +55,17 @@ if ("true" == System.getProperty("idea.sync.active")) { } } + +tasks.named("shadowJar") { + archiveBaseName.set(tasks.getByName("jar").archiveBaseName.orNull) // Pain. Agony, even. + archiveClassifier.set("") // Suffering, if you will. +} + afterEvaluate { - val reobf = extensions.getByName>("reobf") - reobf.maybeCreate("shadowJar").run { - group = "forge" - mappings = tasks.getByName("createMcpToSrg").output + tasks.named("reobfJar") { + val shadow = tasks.getByName("shadowJar"); + dependsOn(shadow) + input = shadow.archiveFile.orNull?.asFile } } @@ -71,7 +77,7 @@ configure { runs { val runConfig = Action { properties(mapOf( - "forge.logging.markers" to "SCAN,REGISTRIES,REGISTRYDUMP", + //"forge.logging.markers" to "SCAN,REGISTRIES,REGISTRYDUMP", "forge.logging.console.level" to "debug" )) arg("-mixin.config=terra.mixins.json") @@ -124,12 +130,12 @@ tasks.jar { } tasks.register("publishModrinthForge") { - dependsOn("reobfShadowJar") + dependsOn("reobfJar") group = "forge" token = System.getenv("MODRINTH_SECRET") projectId = "FIlZB9L0" versionNumber = "${project.version}-forge" - uploadFile = tasks.named("reobfShadowJar").get().input.absoluteFile + uploadFile = tasks.named("reobfJar").get().input.absoluteFile releaseType = "alpha" addGameVersion("1.16.5") addLoader("forge") diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/ForgeAdapter.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/ForgeAdapter.java new file mode 100644 index 000000000..6b9f585d3 --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/ForgeAdapter.java @@ -0,0 +1,90 @@ +package com.dfsek.terra.forge; + +import com.dfsek.terra.api.math.vector.Vector3; +import com.dfsek.terra.api.platform.block.BlockFace; +import com.dfsek.terra.api.platform.block.state.Container; +import com.dfsek.terra.api.platform.block.state.MobSpawner; +import com.dfsek.terra.api.platform.block.state.Sign; +import com.dfsek.terra.forge.block.ForgeBlockData; +import com.dfsek.terra.forge.block.data.ForgeDirectional; +import com.dfsek.terra.forge.block.data.ForgeMultipleFacing; +import com.dfsek.terra.forge.block.data.ForgeOrientable; +import com.dfsek.terra.forge.block.data.ForgeRotatable; +import com.dfsek.terra.forge.block.data.ForgeSlab; +import com.dfsek.terra.forge.block.data.ForgeStairs; +import com.dfsek.terra.forge.block.data.ForgeWaterlogged; +import net.minecraft.block.BlockState; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.tileentity.LockableLootTileEntity; +import net.minecraft.tileentity.MobSpawnerTileEntity; +import net.minecraft.tileentity.SignTileEntity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IWorld; + +import java.util.Arrays; + +public final class ForgeAdapter { + public static BlockPos adapt(Vector3 v) { + return new BlockPos(v.getBlockX(), v.getBlockY(), v.getBlockZ()); + } + + public static Vector3 adapt(BlockPos pos) { + return new Vector3(pos.getX(), pos.getY(), pos.getZ()); + } + + public static ForgeBlockData adapt(BlockState state) { + if(state.hasProperty(BlockStateProperties.STAIRS_SHAPE)) return new ForgeStairs(state); + + if(state.hasProperty(BlockStateProperties.SLAB_TYPE)) return new ForgeSlab(state); + + if(state.hasProperty(BlockStateProperties.AXIS)) return new ForgeOrientable(state, BlockStateProperties.AXIS); + if(state.hasProperty(BlockStateProperties.HORIZONTAL_AXIS)) return new ForgeOrientable(state, BlockStateProperties.HORIZONTAL_AXIS); + + if(state.hasProperty(BlockStateProperties.ROTATION_16)) return new ForgeRotatable(state); + + if(state.hasProperty(BlockStateProperties.FACING)) return new ForgeDirectional(state, BlockStateProperties.FACING); + if(state.hasProperty(BlockStateProperties.FACING_HOPPER)) return new ForgeDirectional(state, BlockStateProperties.FACING_HOPPER); + if(state.hasProperty(BlockStateProperties.HORIZONTAL_FACING)) + return new ForgeDirectional(state, BlockStateProperties.HORIZONTAL_FACING); + + if(state.getProperties().containsAll(Arrays.asList(BlockStateProperties.NORTH, BlockStateProperties.SOUTH, BlockStateProperties.EAST, BlockStateProperties.WEST))) + return new ForgeMultipleFacing(state); + if(state.hasProperty(BlockStateProperties.WATERLOGGED)) return new ForgeWaterlogged(state); + return new ForgeBlockData(state); + } + + public static com.dfsek.terra.api.platform.block.state.BlockState adapt(com.dfsek.terra.api.platform.block.Block block) { + IWorld worldAccess = (IWorld) block.getLocation().getWorld(); + + TileEntity entity = worldAccess.getBlockEntity(adapt(block.getLocation().toVector())); + if(entity instanceof SignTileEntity) { + return (Sign) entity; + } else if(entity instanceof MobSpawnerTileEntity) { + return (MobSpawner) entity; + } else if(entity instanceof LockableLootTileEntity) { + return (Container) entity; + } + return null; + } + + public static Direction adapt(BlockFace face) { + switch(face) { + case NORTH: + return Direction.NORTH; + case WEST: + return Direction.WEST; + case SOUTH: + return Direction.SOUTH; + case EAST: + return Direction.EAST; + case UP: + return Direction.UP; + case DOWN: + return Direction.DOWN; + default: + throw new IllegalArgumentException("Illegal direction: " + face); + } + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/ForgeUtil.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/ForgeUtil.java new file mode 100644 index 000000000..8e112259b --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/ForgeUtil.java @@ -0,0 +1,66 @@ +package com.dfsek.terra.forge; + +import com.dfsek.terra.config.builder.BiomeBuilder; +import com.dfsek.terra.config.pack.ConfigPack; +import com.dfsek.terra.config.templates.BiomeTemplate; +import net.minecraft.block.Blocks; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.BiomeAmbience; +import net.minecraft.world.biome.BiomeGenerationSettings; +import net.minecraft.world.gen.GenerationStage; +import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder; +import net.minecraft.world.gen.surfacebuilders.SurfaceBuilderConfig; + +import java.util.ArrayList; +import java.util.Locale; +import java.util.Map; + +public final class ForgeUtil { + public static String createBiomeID(ConfigPack pack, String biomeID) { + return pack.getTemplate().getID().toLowerCase() + "/" + biomeID.toLowerCase(Locale.ROOT); + } + + @SuppressWarnings("ConstantConditions") + public static Biome createBiome(BiomeBuilder biome) { + BiomeTemplate template = biome.getTemplate(); + Map colors = template.getColors(); + + Biome vanilla = (Biome) ((Object) new ArrayList<>(biome.getVanillaBiomes().getContents()).get(0)); + + BiomeGenerationSettings.Builder generationSettings = new BiomeGenerationSettings.Builder(); + generationSettings.surfaceBuilder(SurfaceBuilder.DEFAULT.configured(new SurfaceBuilderConfig(Blocks.GRASS_BLOCK.defaultBlockState(), Blocks.DIRT.defaultBlockState(), Blocks.GRAVEL.defaultBlockState()))); // It needs a surfacebuilder, even though we dont use it. + generationSettings.addFeature(GenerationStage.Decoration.VEGETAL_DECORATION, TerraForgePlugin.POPULATOR_CONFIGURED_FEATURE); + + BiomeAmbience vanillaEffects = vanilla.getSpecialEffects(); + BiomeAmbience.Builder effects = new BiomeAmbience.Builder() + .waterColor(colors.getOrDefault("water", vanillaEffects.getWaterColor())) + .waterFogColor(colors.getOrDefault("water-fog", vanillaEffects.getWaterFogColor())) + .fogColor(colors.getOrDefault("fog", vanillaEffects.getFogColor())) + .skyColor(colors.getOrDefault("sky", vanillaEffects.getSkyColor())) + .grassColorModifier(vanillaEffects.getGrassColorModifier()); + + if(colors.containsKey("grass")) { + effects.grassColorOverride(colors.get("grass")); + } else { + vanillaEffects.getGrassColorOverride().ifPresent(effects::grassColorOverride); + } + vanillaEffects.getFoliageColorOverride().ifPresent(effects::foliageColorOverride); + if(colors.containsKey("foliage")) { + effects.foliageColorOverride(colors.get("foliage")); + } else { + vanillaEffects.getFoliageColorOverride().ifPresent(effects::foliageColorOverride); + } + + return new Biome.Builder() + .precipitation(vanilla.getPrecipitation()) + .biomeCategory(vanilla.getBiomeCategory()) + .depth(vanilla.getDepth()) + .scale(vanilla.getScale()) + .temperature(vanilla.getBaseTemperature()) + .downfall(vanilla.getDownfall()) + .specialEffects(effects.build()) + .mobSpawnSettings(vanilla.getMobSettings()) + .generationSettings(generationSettings.build()) + .build().setRegistryName("terra", createBiomeID(template.getPack(), template.getID())); + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/TerraForgePlugin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/TerraForgePlugin.java index b7cab9f61..993766056 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/TerraForgePlugin.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/TerraForgePlugin.java @@ -8,7 +8,6 @@ import com.dfsek.terra.api.addons.annotations.Author; import com.dfsek.terra.api.addons.annotations.Version; import com.dfsek.terra.api.command.CommandManager; import com.dfsek.terra.api.command.TerraCommandManager; -import com.dfsek.terra.api.command.exception.CommandException; import com.dfsek.terra.api.command.exception.MalformedCommandException; import com.dfsek.terra.api.event.EventListener; import com.dfsek.terra.api.event.EventManager; @@ -16,7 +15,6 @@ import com.dfsek.terra.api.event.TerraEventManager; import com.dfsek.terra.api.event.annotations.Global; import com.dfsek.terra.api.event.annotations.Priority; import com.dfsek.terra.api.event.events.config.ConfigPackPreLoadEvent; -import com.dfsek.terra.api.platform.CommandSender; import com.dfsek.terra.api.platform.block.BlockData; import com.dfsek.terra.api.platform.handle.ItemHandle; import com.dfsek.terra.api.platform.handle.WorldHandle; @@ -28,62 +26,35 @@ import com.dfsek.terra.api.transform.NotNullValidator; import com.dfsek.terra.api.transform.Transformer; import com.dfsek.terra.api.util.JarUtil; import com.dfsek.terra.api.util.logging.DebugLogger; -import com.dfsek.terra.api.util.mutable.MutableInteger; import com.dfsek.terra.commands.CommandUtil; import com.dfsek.terra.config.GenericLoaders; import com.dfsek.terra.config.PluginConfig; -import com.dfsek.terra.config.builder.BiomeBuilder; import com.dfsek.terra.config.lang.LangUtil; import com.dfsek.terra.config.lang.Language; import com.dfsek.terra.config.pack.ConfigPack; -import com.dfsek.terra.config.templates.BiomeTemplate; -import com.dfsek.terra.forge.inventory.ForgeItemHandle; -import com.dfsek.terra.forge.world.ForgeAdapter; -import com.dfsek.terra.forge.world.ForgeBiome; -import com.dfsek.terra.forge.world.ForgeTree; -import com.dfsek.terra.forge.world.ForgeWorldHandle; -import com.dfsek.terra.forge.world.features.PopulatorFeature; -import com.dfsek.terra.forge.world.generator.ForgeChunkGenerator; -import com.dfsek.terra.forge.world.generator.ForgeChunkGeneratorWrapper; -import com.dfsek.terra.forge.world.generator.config.TerraLevelType; +import com.dfsek.terra.forge.generation.ForgeChunkGeneratorWrapper; +import com.dfsek.terra.forge.generation.PopulatorFeature; +import com.dfsek.terra.forge.generation.TerraBiomeSource; +import com.dfsek.terra.forge.handle.ForgeItemHandle; +import com.dfsek.terra.forge.handle.ForgeWorldHandle; 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.world.TerraWorld; -import com.mojang.brigadier.arguments.StringArgumentType; -import com.mojang.brigadier.builder.ArgumentBuilder; -import com.mojang.brigadier.builder.RequiredArgumentBuilder; -import net.minecraft.block.Blocks; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.widget.button.Button; -import net.minecraft.command.CommandSource; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.text.StringTextComponent; +import net.minecraft.util.registry.Registry; import net.minecraft.world.biome.Biome; -import net.minecraft.world.biome.BiomeAmbience; -import net.minecraft.world.biome.BiomeGenerationSettings; -import net.minecraft.world.gen.GenerationStage; import net.minecraft.world.gen.feature.ConfiguredFeature; -import net.minecraft.world.gen.feature.Feature; import net.minecraft.world.gen.feature.Features; import net.minecraft.world.gen.feature.IFeatureConfig; import net.minecraft.world.gen.feature.NoFeatureConfig; import net.minecraft.world.gen.placement.DecoratedPlacement; import net.minecraft.world.gen.placement.NoPlacementConfig; -import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder; -import net.minecraft.world.gen.surfacebuilders.SurfaceBuilderConfig; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.client.ForgeWorldTypeScreens; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.world.ForgeWorldType; -import net.minecraftforge.event.RegisterCommandsEvent; -import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.registries.ForgeRegistries; import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; @@ -94,20 +65,12 @@ import java.io.IOException; import java.io.InputStream; import java.net.URISyntaxException; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; -import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Objects; -import java.util.function.Consumer; import java.util.jar.JarFile; import java.util.zip.ZipFile; -import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal; -import static com.mojang.brigadier.builder.RequiredArgumentBuilder.argument; - @Mod("terra") @Mod.EventBusSubscriber(modid = "terra", bus = Mod.EventBusSubscriber.Bus.MOD) public class TerraForgePlugin implements TerraPlugin { @@ -140,6 +103,7 @@ public class TerraForgePlugin implements TerraPlugin { logger.error(message); } }; + private final DebugLogger debugLogger = new DebugLogger(logger); private final ItemHandle itemHandle = new ForgeItemHandle(); private final WorldHandle worldHandle = new ForgeWorldHandle(); @@ -151,118 +115,35 @@ public class TerraForgePlugin implements TerraPlugin { private final Transformer biomeFixer = new Transformer.Builder() .addTransform(id -> ForgeRegistries.BIOMES.getValue(ResourceLocation.tryParse(id)), new NotNullValidator<>()) .addTransform(id -> ForgeRegistries.BIOMES.getValue(ResourceLocation.tryParse("minecraft:" + id.toLowerCase())), new NotNullValidator<>()).build(); - private File dataFolder; + private final File dataFolder; public TerraForgePlugin() { if(INSTANCE != null) throw new IllegalStateException("Only one TerraPlugin instance may exist."); INSTANCE = this; - MinecraftForge.EVENT_BUS.register(ClientEvents.class); - MinecraftForge.EVENT_BUS.register(getClass()); - MinecraftForge.EVENT_BUS.register(ForgeEvents.class); + this.dataFolder = Paths.get("config", "Terra").toFile(); + saveDefaultConfig(); + config.load(this); + LangUtil.load(config.getLanguage(), this); + try { + CommandUtil.registerAll(manager); + } catch(MalformedCommandException e) { + e.printStackTrace(); // TODO do something here even though this should literally never happen + } } public static TerraForgePlugin getInstance() { return INSTANCE; } - public static String createBiomeID(ConfigPack pack, String biomeID) { - return pack.getTemplate().getID().toLowerCase() + "/" + biomeID.toLowerCase(Locale.ROOT); - } - - private static RequiredArgumentBuilder assemble(RequiredArgumentBuilder in, CommandManager manager) { - return in.suggests((context, builder) -> { - List args = parseCommand(context.getInput()); - CommandSender sender = ForgeAdapter.adapt(context.getSource()); - try { - manager.tabComplete(args.remove(0), sender, args).forEach(builder::suggest); - } catch(CommandException e) { - sender.sendMessage(e.getMessage()); - } - return builder.buildFuture(); - }).executes(context -> { - List args = parseCommand(context.getInput()); - try { - manager.execute(args.remove(0), ForgeAdapter.adapt(context.getSource()), args); - } catch(CommandException e) { - context.getSource().sendFailure(new StringTextComponent(e.getMessage())); - } - return 1; + @SubscribeEvent + public static void setupListener(FMLCommonSetupEvent event) { + event.enqueueWork(() -> { + Registry.register(Registry.BIOME_SOURCE, "terra:biome", TerraBiomeSource.CODEC); + Registry.register(Registry.CHUNK_GENERATOR, "terra:generator", ForgeChunkGeneratorWrapper.CODEC); }); } - private static List parseCommand(String command) { - if(command.startsWith("/terra ")) command = command.substring("/terra ".length()); - else if(command.startsWith("/te ")) command = command.substring("/te ".length()); - List c = new ArrayList<>(Arrays.asList(command.split(" "))); - if(command.endsWith(" ")) c.add(""); - return c; - } - - @SubscribeEvent - public static void register(RegistryEvent.Register event) { - INSTANCE.setup(); // Setup now because we need the biomes, and this event happens after blocks n stuff - INSTANCE.getConfigRegistry().forEach(pack -> pack.getBiomeRegistry().forEach((id, biome) -> event.getRegistry().register(INSTANCE.createBiome(biome)))); // Register all Terra biomes. - } - - @SubscribeEvent - public static void registerLevels(RegistryEvent.Register event) { - INSTANCE.logger().info("Registering level types..."); - event.getRegistry().register(TerraLevelType.FORGE_WORLD_TYPE); - } - - @SubscribeEvent - public static void registerPop(RegistryEvent.Register> event) { - event.getRegistry().register(POPULATOR_FEATURE); - } - - public Biome createBiome(BiomeBuilder biome) { - BiomeTemplate template = biome.getTemplate(); - Map colors = template.getColors(); - - Biome vanilla = ((ForgeBiome) new ArrayList<>(biome.getVanillaBiomes().getContents()).get(0)).getHandle(); - - BiomeGenerationSettings.Builder generationSettings = new BiomeGenerationSettings.Builder(); - generationSettings.surfaceBuilder(SurfaceBuilder.DEFAULT.configured(new SurfaceBuilderConfig(Blocks.GRASS_BLOCK.defaultBlockState(), Blocks.DIRT.defaultBlockState(), Blocks.GRAVEL.defaultBlockState()))); // It needs a surfacebuilder, even though we dont use it. - generationSettings.addFeature(GenerationStage.Decoration.VEGETAL_DECORATION, POPULATOR_CONFIGURED_FEATURE); - - BiomeAmbience vanillaEffects = vanilla.getSpecialEffects(); - BiomeAmbience.Builder effects = new BiomeAmbience.Builder() - .waterColor(colors.getOrDefault("water", vanillaEffects.getWaterColor())) - .waterFogColor(colors.getOrDefault("water-fog", vanillaEffects.getWaterFogColor())) - .fogColor(colors.getOrDefault("fog", vanillaEffects.getFogColor())) - .skyColor(colors.getOrDefault("sky", vanillaEffects.getSkyColor())) - .grassColorModifier(vanillaEffects.getGrassColorModifier()); - - if(colors.containsKey("grass")) { - effects.grassColorOverride(colors.get("grass")); - } else { - vanillaEffects.getGrassColorOverride().ifPresent(effects::grassColorOverride); - } - vanillaEffects.getFoliageColorOverride().ifPresent(effects::foliageColorOverride); - if(colors.containsKey("foliage")) { - effects.foliageColorOverride(colors.get("foliage")); - } else { - vanillaEffects.getFoliageColorOverride().ifPresent(effects::foliageColorOverride); - } - - return new Biome.Builder() - .precipitation(vanilla.getPrecipitation()) - .biomeCategory(vanilla.getBiomeCategory()) - .depth(vanilla.getDepth()) - .scale(vanilla.getScale()) - .temperature(vanilla.getBaseTemperature()) - .downfall(vanilla.getDownfall()) - .specialEffects(effects.build()) - .mobSpawnSettings(vanilla.getMobSettings()) - .generationSettings(generationSettings.build()) - .build().setRegistryName("terra", createBiomeID(template.getPack(), template.getID())); - } - public void setup() { - this.dataFolder = Paths.get("config", "Terra").toFile(); - saveDefaultConfig(); - config.load(this); - LangUtil.load(config.getLanguage(), this); logger.info("Initializing Terra..."); if(!addonRegistry.loadAll()) { @@ -271,15 +152,7 @@ public class TerraForgePlugin implements TerraPlugin { logger.info("Loaded addons."); registry.loadAll(this); - logger.info("Loaded packs."); - - - try { - CommandUtil.registerAll(manager); - } catch(MalformedCommandException e) { - e.printStackTrace(); // TODO do something here even though this should literally never happen - } } @Override @@ -291,10 +164,17 @@ public class TerraForgePlugin implements TerraPlugin { public TerraWorld getWorld(World world) { return worldMap.computeIfAbsent(world.getSeed(), w -> { logger.info("Loading world " + w); - return new TerraWorld(world, ((ForgeChunkGeneratorWrapper) ((ForgeChunkGenerator) world.getGenerator()).getHandle()).getPack(), this); + return new TerraWorld(world, ((ForgeChunkGeneratorWrapper) world.getGenerator()).getPack(), this); }); } + /** + * evil code brought to you by Forge Mod Loader + *

+ * Forge changes the JAR URI to something that cannot + * be resolved back to the original JAR, so we have to + * do this to get our JAR. + */ @Override public JarFile getModJar() throws URISyntaxException, IOException { File modsDir = new File("./mods"); @@ -334,7 +214,7 @@ public class TerraForgePlugin implements TerraPlugin { @Override public boolean isDebug() { - return true; + return config.isDebug(); } @Override @@ -398,7 +278,7 @@ public class TerraForgePlugin implements TerraPlugin { genericLoaders.register(registry); registry .registerLoader(BlockData.class, (t, o, l) -> worldHandle.createBlockData((String) o)) - .registerLoader(com.dfsek.terra.api.platform.world.Biome.class, (t, o, l) -> new ForgeBiome(biomeFixer.translate((String) o))); + .registerLoader(com.dfsek.terra.api.platform.world.Biome.class, (t, o, l) -> biomeFixer.translate((String) o)); } @Override @@ -411,22 +291,8 @@ public class TerraForgePlugin implements TerraPlugin { return profiler; } - @Mod.EventBusSubscriber(modid = "terra", bus = Mod.EventBusSubscriber.Bus.FORGE) - public static final class ForgeEvents { - @SuppressWarnings({"unchecked", "rawtypes"}) - @SubscribeEvent - public static void registerCommands(RegisterCommandsEvent event) { - int max = INSTANCE.manager.getMaxArgumentDepth(); - RequiredArgumentBuilder arg = argument("arg" + (max - 1), StringArgumentType.word()); - for(int i = 0; i < max; i++) { - RequiredArgumentBuilder next = argument("arg" + (max - i - 1), StringArgumentType.word()); - - arg = next.then(assemble(arg, INSTANCE.manager)); - } - - event.getDispatcher().register(literal("terra").executes(context -> 1).then((ArgumentBuilder) assemble(arg, INSTANCE.manager))); - event.getDispatcher().register(literal("te").executes(context -> 1).then((ArgumentBuilder) assemble(arg, INSTANCE.manager))); - } + public CommandManager getManager() { + return manager; } @Addon("Terra-Forge") @@ -473,38 +339,9 @@ public class TerraForgePlugin implements TerraPlugin { private void injectTree(CheckedRegistry registry, String id, ConfiguredFeature tree) { try { - registry.add(id, new ForgeTree(tree, id, TerraForgePlugin.getInstance())); + registry.add(id, (Tree) tree); } catch(DuplicateEntryException ignore) { } } } - - @Mod.EventBusSubscriber(value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD) - public static final class ClientEvents { - @SubscribeEvent - public static void register(FMLClientSetupEvent event) { - INSTANCE.logger.info("Client setup..."); - - ForgeWorldType world = TerraLevelType.FORGE_WORLD_TYPE; - ForgeWorldTypeScreens.registerFactory(world, (returnTo, dimensionGeneratorSettings) -> new Screen(world.getDisplayName()) { - private final MutableInteger num = new MutableInteger(0); - private final List packs = new ArrayList<>(); - private final Button toggle = new Button(0, 25, 120, 20, new StringTextComponent(""), button -> { - num.increment(); - if(num.get() >= packs.size()) num.set(0); - button.setMessage(new StringTextComponent("Pack: " + packs.get(num.get()).getTemplate().getID())); - }); - - @Override - protected void init() { - packs.clear(); - INSTANCE.registry.forEach((Consumer) packs::add); - addButton(new Button(0, 0, 120, 20, new StringTextComponent("Close"), btn -> Minecraft.getInstance().setScreen(returnTo))); - toggle.setMessage(new StringTextComponent("Pack: " + packs.get(num.get()).getTemplate().getID())); - addButton(toggle); - } - }); - } - } - } diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/ForgeBlock.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/ForgeBlock.java similarity index 89% rename from platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/ForgeBlock.java rename to platforms/forge/src/main/java/com/dfsek/terra/forge/block/ForgeBlock.java index 3d439d5d0..98ad4d61e 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/ForgeBlock.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/ForgeBlock.java @@ -1,4 +1,4 @@ -package com.dfsek.terra.forge.world.block; +package com.dfsek.terra.forge.block; import com.dfsek.terra.api.math.vector.Location; import com.dfsek.terra.api.platform.block.Block; @@ -6,9 +6,8 @@ import com.dfsek.terra.api.platform.block.BlockData; import com.dfsek.terra.api.platform.block.BlockFace; import com.dfsek.terra.api.platform.block.BlockType; import com.dfsek.terra.api.platform.block.state.BlockState; -import com.dfsek.terra.forge.world.ForgeAdapter; -import com.dfsek.terra.forge.world.block.state.ForgeBlockState; -import com.dfsek.terra.forge.world.handles.world.ForgeWorldAccess; +import com.dfsek.terra.api.platform.world.World; +import com.dfsek.terra.forge.ForgeAdapter; import net.minecraft.block.FlowingFluidBlock; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IWorld; @@ -35,7 +34,7 @@ public class ForgeBlock implements Block { @Override public BlockState getState() { - return ForgeBlockState.newInstance(this); + return ForgeAdapter.adapt(this); } @Override @@ -51,7 +50,7 @@ public class ForgeBlock implements Block { @Override public Location getLocation() { - return ForgeAdapter.adapt(delegate.position).toLocation(new ForgeWorldAccess(delegate.worldAccess)); + return ForgeAdapter.adapt(delegate.position).toLocation((World) delegate.worldAccess); } @Override diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/ForgeBlockData.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/ForgeBlockData.java similarity index 94% rename from platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/ForgeBlockData.java rename to platforms/forge/src/main/java/com/dfsek/terra/forge/block/ForgeBlockData.java index 1a4ddb4b5..1fb22ec35 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/ForgeBlockData.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/ForgeBlockData.java @@ -1,8 +1,7 @@ -package com.dfsek.terra.forge.world.block; +package com.dfsek.terra.forge.block; import com.dfsek.terra.api.platform.block.BlockData; import com.dfsek.terra.api.platform.block.BlockType; -import com.dfsek.terra.forge.world.ForgeAdapter; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.state.Property; @@ -39,7 +38,7 @@ public class ForgeBlockData implements BlockData { @Override public BlockType getBlockType() { - return ForgeAdapter.adapt(delegate.getBlock()); + return (BlockType) delegate.getBlock(); } @Override diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeAnaloguePowerable.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeAnaloguePowerable.java similarity index 84% rename from platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeAnaloguePowerable.java rename to platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeAnaloguePowerable.java index ff59ff1be..f8455c5c7 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeAnaloguePowerable.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeAnaloguePowerable.java @@ -1,7 +1,7 @@ -package com.dfsek.terra.forge.world.block.data; +package com.dfsek.terra.forge.block.data; import com.dfsek.terra.api.platform.block.data.AnaloguePowerable; -import com.dfsek.terra.forge.world.block.ForgeBlockData; +import com.dfsek.terra.forge.block.ForgeBlockData; import net.minecraft.block.BlockState; /** diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeDirectional.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeDirectional.java similarity index 88% rename from platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeDirectional.java rename to platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeDirectional.java index ec7c34242..c4cc15636 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeDirectional.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeDirectional.java @@ -1,9 +1,9 @@ -package com.dfsek.terra.forge.world.block.data; +package com.dfsek.terra.forge.block.data; import com.dfsek.terra.api.platform.block.BlockFace; import com.dfsek.terra.api.platform.block.data.Directional; -import com.dfsek.terra.forge.world.ForgeAdapter; -import com.dfsek.terra.forge.world.block.ForgeBlockData; +import com.dfsek.terra.forge.ForgeAdapter; +import com.dfsek.terra.forge.block.ForgeBlockData; import net.minecraft.block.BlockState; import net.minecraft.state.DirectionProperty; diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeEnumAdapter.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeEnumAdapter.java similarity index 98% rename from platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeEnumAdapter.java rename to platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeEnumAdapter.java index d01c59f37..16ba0bb8a 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeEnumAdapter.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeEnumAdapter.java @@ -1,4 +1,4 @@ -package com.dfsek.terra.forge.world.block.data; +package com.dfsek.terra.forge.block.data; import com.dfsek.terra.api.platform.block.Axis; import com.dfsek.terra.api.platform.block.BlockFace; diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeMultipleFacing.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeMultipleFacing.java similarity index 96% rename from platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeMultipleFacing.java rename to platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeMultipleFacing.java index 4bfde3fcc..7e9510282 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeMultipleFacing.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeMultipleFacing.java @@ -1,12 +1,11 @@ -package com.dfsek.terra.forge.world.block.data; +package com.dfsek.terra.forge.block.data; import com.dfsek.terra.api.platform.block.BlockFace; import com.dfsek.terra.api.platform.block.data.MultipleFacing; -import com.dfsek.terra.forge.world.block.ForgeBlockData; +import com.dfsek.terra.forge.block.ForgeBlockData; import net.minecraft.block.BlockState; import net.minecraft.state.properties.BlockStateProperties; - import java.util.HashSet; import java.util.Set; diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeOrientable.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeOrientable.java similarity index 90% rename from platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeOrientable.java rename to platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeOrientable.java index 39d3aa7f6..9f3e53f2d 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeOrientable.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeOrientable.java @@ -1,13 +1,12 @@ -package com.dfsek.terra.forge.world.block.data; +package com.dfsek.terra.forge.block.data; import com.dfsek.terra.api.platform.block.Axis; import com.dfsek.terra.api.platform.block.data.Orientable; -import com.dfsek.terra.forge.world.block.ForgeBlockData; +import com.dfsek.terra.forge.block.ForgeBlockData; import net.minecraft.block.BlockState; import net.minecraft.state.EnumProperty; import net.minecraft.util.Direction; - import java.util.Arrays; import java.util.Set; import java.util.stream.Collectors; diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeRotatable.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeRotatable.java similarity index 97% rename from platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeRotatable.java rename to platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeRotatable.java index 70bc30111..b64727b59 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeRotatable.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeRotatable.java @@ -1,8 +1,8 @@ -package com.dfsek.terra.forge.world.block.data; +package com.dfsek.terra.forge.block.data; import com.dfsek.terra.api.platform.block.BlockFace; import com.dfsek.terra.api.platform.block.data.Rotatable; -import com.dfsek.terra.forge.world.block.ForgeBlockData; +import com.dfsek.terra.forge.block.ForgeBlockData; import net.minecraft.block.BlockState; import net.minecraft.state.properties.BlockStateProperties; diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeSlab.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeSlab.java similarity index 92% rename from platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeSlab.java rename to platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeSlab.java index 55c8daa2a..4f294604e 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeSlab.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeSlab.java @@ -1,4 +1,4 @@ -package com.dfsek.terra.forge.world.block.data; +package com.dfsek.terra.forge.block.data; import com.dfsek.terra.api.platform.block.data.Slab; import net.minecraft.block.BlockState; diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeStairs.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeStairs.java similarity index 96% rename from platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeStairs.java rename to platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeStairs.java index 87fae372d..ef9c6e8ff 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeStairs.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeStairs.java @@ -1,4 +1,4 @@ -package com.dfsek.terra.forge.world.block.data; +package com.dfsek.terra.forge.block.data; import com.dfsek.terra.api.platform.block.BlockFace; import com.dfsek.terra.api.platform.block.data.Stairs; diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeWaterlogged.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeWaterlogged.java similarity index 85% rename from platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeWaterlogged.java rename to platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeWaterlogged.java index c67aa0be0..ed6abffbe 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/data/ForgeWaterlogged.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/block/data/ForgeWaterlogged.java @@ -1,7 +1,7 @@ -package com.dfsek.terra.forge.world.block.data; +package com.dfsek.terra.forge.block.data; import com.dfsek.terra.api.platform.block.data.Waterlogged; -import com.dfsek.terra.forge.world.block.ForgeBlockData; +import com.dfsek.terra.forge.block.ForgeBlockData; import net.minecraft.block.BlockState; import net.minecraft.state.properties.BlockStateProperties; diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/generator/ForgeChunkGeneratorWrapper.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/generation/ForgeChunkGeneratorWrapper.java similarity index 86% rename from platforms/forge/src/main/java/com/dfsek/terra/forge/world/generator/ForgeChunkGeneratorWrapper.java rename to platforms/forge/src/main/java/com/dfsek/terra/forge/generation/ForgeChunkGeneratorWrapper.java index e9a5ce20d..5414d05ab 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/generator/ForgeChunkGeneratorWrapper.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/generation/ForgeChunkGeneratorWrapper.java @@ -1,12 +1,12 @@ -package com.dfsek.terra.forge.world.generator; +package com.dfsek.terra.forge.generation; +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.generation.TerraChunkGenerator; import com.dfsek.terra.config.pack.ConfigPack; import com.dfsek.terra.forge.TerraForgePlugin; -import com.dfsek.terra.forge.world.TerraBiomeSource; -import com.dfsek.terra.forge.world.handles.world.ForgeSeededWorldAccess; import com.dfsek.terra.world.TerraWorld; import com.dfsek.terra.world.generation.generators.DefaultChunkGenerator3D; import com.dfsek.terra.world.generation.math.samplers.Sampler; @@ -21,7 +21,6 @@ import net.minecraft.world.Blockreader; import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorld; import net.minecraft.world.biome.BiomeManager; -import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.IChunk; import net.minecraft.world.gen.ChunkGenerator; import net.minecraft.world.gen.GenerationStage; @@ -30,7 +29,6 @@ import net.minecraft.world.gen.WorldGenRegion; import net.minecraft.world.gen.feature.structure.StructureManager; import net.minecraft.world.gen.feature.template.TemplateManager; import net.minecraft.world.gen.settings.DimensionStructuresSettings; -import net.minecraft.world.gen.settings.StructureSpreadSettings; import org.jetbrains.annotations.NotNull; public class ForgeChunkGeneratorWrapper extends ChunkGenerator implements GeneratorWrapper { @@ -83,19 +81,18 @@ public class ForgeChunkGeneratorWrapper extends ChunkGenerator implements Genera } @Override - public void createStructures(@NotNull DynamicRegistries p_242707_1_, @NotNull StructureManager p_242707_2_, @NotNull IChunk p_242707_3_, @NotNull TemplateManager p_242707_4_, long p_242707_5_) { - + public void createStructures(@NotNull DynamicRegistries dynamicRegistries, @NotNull StructureManager manager, @NotNull IChunk chunk, @NotNull TemplateManager templateManager, long p_242707_5_) { + if(pack.getTemplate().vanillaStructures()) super.createStructures(dynamicRegistries, manager, chunk, templateManager, p_242707_5_); } @Override - public void applyCarvers(long p_230350_1_, @NotNull BiomeManager p_230350_3_, @NotNull IChunk p_230350_4_, GenerationStage.@NotNull Carving p_230350_5_) { - // No caves + public void applyCarvers(long p_230350_1_, @NotNull BiomeManager biomeManager, @NotNull IChunk chunk, GenerationStage.@NotNull Carving carving) { + if(pack.getTemplate().vanillaCaves()) super.applyCarvers(p_230350_1_, biomeManager, chunk, carving); } @Override public void fillFromNoise(@NotNull IWorld world, @NotNull StructureManager p_230352_2_, @NotNull IChunk chunk) { - ForgeSeededWorldAccess worldAccess = new ForgeSeededWorldAccess(world, seed, this); - delegate.generateChunkData(worldAccess, new FastRandom(), chunk.getPos().x, chunk.getPos().z, new ForgeChunkData(chunk)); + delegate.generateChunkData((World) world, new FastRandom(), chunk.getPos().x, chunk.getPos().z, (ChunkData) chunk); } @Override diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/features/PopulatorFeature.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/generation/PopulatorFeature.java similarity index 55% rename from platforms/forge/src/main/java/com/dfsek/terra/forge/world/features/PopulatorFeature.java rename to platforms/forge/src/main/java/com/dfsek/terra/forge/generation/PopulatorFeature.java index 6082b4d4e..e586e82d4 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/features/PopulatorFeature.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/generation/PopulatorFeature.java @@ -1,9 +1,7 @@ -package com.dfsek.terra.forge.world.features; +package com.dfsek.terra.forge.generation; -import com.dfsek.terra.forge.world.generator.ForgeChunkGenerator; -import com.dfsek.terra.forge.world.generator.ForgeChunkGeneratorWrapper; -import com.dfsek.terra.forge.world.handles.ForgeWorld; -import com.dfsek.terra.forge.world.handles.chunk.ForgeChunkWorldAccess; +import com.dfsek.terra.api.platform.world.Chunk; +import com.dfsek.terra.api.platform.world.World; import com.mojang.serialization.Codec; import net.minecraft.util.math.BlockPos; import net.minecraft.world.ISeedReader; @@ -23,11 +21,9 @@ public class PopulatorFeature extends Feature { } @Override - public boolean place(@NotNull ISeedReader world, @NotNull ChunkGenerator generator, @NotNull Random random, BlockPos pos, @NotNull NoFeatureConfig config) { + public boolean place(@NotNull ISeedReader world, @NotNull ChunkGenerator generator, @NotNull Random random, @NotNull BlockPos pos, @NotNull NoFeatureConfig config) { ForgeChunkGeneratorWrapper gen = (ForgeChunkGeneratorWrapper) generator; - ForgeChunkWorldAccess chunk = new ForgeChunkWorldAccess(world, pos.getX() >> 4, pos.getZ() >> 4); - ForgeWorld world1 = new ForgeWorld(world.getLevel(), new ForgeChunkGenerator(generator)); - gen.getHandle().getPopulators().forEach(populator -> populator.populate(world1, chunk)); + gen.getHandle().getPopulators().forEach(populator -> populator.populate((World) world, (Chunk) world)); return true; } diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/TerraBiomeSource.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/generation/TerraBiomeSource.java similarity index 94% rename from platforms/forge/src/main/java/com/dfsek/terra/forge/world/TerraBiomeSource.java rename to platforms/forge/src/main/java/com/dfsek/terra/forge/generation/TerraBiomeSource.java index 5f87a10b1..3220cfd58 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/TerraBiomeSource.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/generation/TerraBiomeSource.java @@ -1,8 +1,9 @@ -package com.dfsek.terra.forge.world; +package com.dfsek.terra.forge.generation; 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.forge.ForgeUtil; import com.dfsek.terra.forge.TerraForgePlugin; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -51,6 +52,6 @@ public class TerraBiomeSource extends net.minecraft.world.biome.provider.BiomePr @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", TerraForgePlugin.createBiomeID(pack, biome.getID())))); + return Objects.requireNonNull(biomeRegistry.get(new ResourceLocation("terra", ForgeUtil.createBiomeID(pack, biome.getID())))); } } diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/generator/config/TerraLevelType.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/generation/TerraLevelType.java similarity index 87% rename from platforms/forge/src/main/java/com/dfsek/terra/forge/world/generator/config/TerraLevelType.java rename to platforms/forge/src/main/java/com/dfsek/terra/forge/generation/TerraLevelType.java index 2d8503af7..945ff4c33 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/generator/config/TerraLevelType.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/generation/TerraLevelType.java @@ -1,9 +1,7 @@ -package com.dfsek.terra.forge.world.generator.config; +package com.dfsek.terra.forge.generation; import com.dfsek.terra.config.pack.ConfigPack; import com.dfsek.terra.forge.TerraForgePlugin; -import com.dfsek.terra.forge.world.TerraBiomeSource; -import com.dfsek.terra.forge.world.generator.ForgeChunkGeneratorWrapper; import net.minecraft.util.registry.Registry; import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.ChunkGenerator; diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/ForgeItemHandle.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/handle/ForgeItemHandle.java similarity index 69% rename from platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/ForgeItemHandle.java rename to platforms/forge/src/main/java/com/dfsek/terra/forge/handle/ForgeItemHandle.java index 6639b4a59..e2dc4185a 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/ForgeItemHandle.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/handle/ForgeItemHandle.java @@ -1,14 +1,12 @@ -package com.dfsek.terra.forge.inventory; +package com.dfsek.terra.forge.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 com.dfsek.terra.forge.world.ForgeAdapter; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.minecraft.command.arguments.ItemArgument; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.registry.Registry; import net.minecraftforge.registries.ForgeRegistries; import java.util.Set; @@ -19,7 +17,7 @@ public class ForgeItemHandle implements ItemHandle { @Override public Item createItem(String data) { try { - return ForgeAdapter.adapt(new ItemArgument().parse(new StringReader(data)).getItem()); + return (Item) new ItemArgument().parse(new StringReader(data)).getItem(); } catch(CommandSyntaxException e) { throw new IllegalArgumentException("Invalid item data \"" + data + "\"", e); } @@ -27,11 +25,11 @@ public class ForgeItemHandle implements ItemHandle { @Override public Enchantment getEnchantment(String id) { - return ForgeAdapter.adapt(ForgeRegistries.ENCHANTMENTS.getValue(ResourceLocation.tryParse(id))); + return (Enchantment) ForgeRegistries.ENCHANTMENTS.getValue(ResourceLocation.tryParse(id)); } @Override public Set getEnchantments() { - return ForgeRegistries.ENCHANTMENTS.getEntries().stream().map(entry -> ForgeAdapter.adapt(entry.getValue())).collect(Collectors.toSet()); + return ForgeRegistries.ENCHANTMENTS.getEntries().stream().map(entry -> (Enchantment) entry.getValue()).collect(Collectors.toSet()); } } diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/ForgeWorldHandle.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/handle/ForgeWorldHandle.java similarity index 84% rename from platforms/forge/src/main/java/com/dfsek/terra/forge/world/ForgeWorldHandle.java rename to platforms/forge/src/main/java/com/dfsek/terra/forge/handle/ForgeWorldHandle.java index 8e4cfafe6..96c2e37fa 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/ForgeWorldHandle.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/handle/ForgeWorldHandle.java @@ -1,14 +1,14 @@ -package com.dfsek.terra.forge.world; +package com.dfsek.terra.forge.handle; import com.dfsek.terra.api.platform.entity.EntityType; import com.dfsek.terra.api.platform.handle.WorldHandle; -import com.dfsek.terra.forge.world.block.ForgeBlockData; +import com.dfsek.terra.forge.ForgeAdapter; +import com.dfsek.terra.forge.block.ForgeBlockData; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.minecraft.block.BlockState; import net.minecraft.command.arguments.BlockStateParser; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.registry.Registry; import net.minecraftforge.registries.ForgeRegistries; import java.util.Locale; @@ -31,6 +31,6 @@ public class ForgeWorldHandle implements WorldHandle { public EntityType getEntity(String id) { ResourceLocation identifier = ResourceLocation.tryParse(id); if(identifier == null) identifier = ResourceLocation.tryParse("minecraft:" + id.toLowerCase(Locale.ROOT)); - return ForgeAdapter.adapt(ForgeRegistries.ENTITIES.getValue(identifier)); + return (EntityType) ForgeRegistries.ENTITIES.getValue(identifier); } } diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/ForgeEnchantment.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/ForgeEnchantment.java deleted file mode 100644 index 8517c7118..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/ForgeEnchantment.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.dfsek.terra.forge.inventory; - -import com.dfsek.terra.api.platform.inventory.ItemStack; -import com.dfsek.terra.api.platform.inventory.item.Enchantment; -import com.dfsek.terra.forge.world.ForgeAdapter; -import net.minecraft.util.registry.Registry; -import net.minecraftforge.registries.ForgeRegistries; - -import java.util.Objects; - -public class ForgeEnchantment implements Enchantment { - private final net.minecraft.enchantment.Enchantment enchantment; - - public ForgeEnchantment(net.minecraft.enchantment.Enchantment enchantment) { - this.enchantment = enchantment; - } - - @Override - public net.minecraft.enchantment.Enchantment getHandle() { - return enchantment; - } - - @Override - public boolean canEnchantItem(ItemStack itemStack) { - return enchantment.canEnchant(ForgeAdapter.adapt(itemStack)); - } - - @Override - public String getID() { - return Objects.requireNonNull(ForgeRegistries.ENCHANTMENTS.getKey(enchantment)).toString(); - } - - @Override - public boolean conflictsWith(Enchantment other) { - return !enchantment.isCompatibleWith(ForgeAdapter.adapt(other)); - } - - @Override - public int getMaxLevel() { - return enchantment.getMaxLevel(); - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/ForgeInventory.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/ForgeInventory.java deleted file mode 100644 index 3109b1498..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/ForgeInventory.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.dfsek.terra.forge.inventory; - -import com.dfsek.terra.api.platform.inventory.Inventory; -import com.dfsek.terra.api.platform.inventory.ItemStack; -import com.dfsek.terra.forge.world.ForgeAdapter; -import net.minecraft.inventory.IInventory; -import net.minecraft.item.Items; - -public class ForgeInventory implements Inventory { - private final net.minecraft.inventory.IInventory delegate; - - public ForgeInventory(IInventory delegate) { - this.delegate = delegate; - } - - @Override - public net.minecraft.inventory.IInventory getHandle() { - return delegate; - } - - @Override - public int getSize() { - return delegate.getContainerSize(); - } - - @Override - public ItemStack getItem(int slot) { - net.minecraft.item.ItemStack itemStack = delegate.getItem(slot); - return itemStack.getItem() == Items.AIR ? null : ForgeAdapter.adapt(itemStack); - } - - @Override - public void setItem(int slot, ItemStack newStack) { - delegate.setItem(slot, ForgeAdapter.adapt(newStack)); - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/ForgeItem.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/ForgeItem.java deleted file mode 100644 index 2f332f768..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/ForgeItem.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.dfsek.terra.forge.inventory; - -import com.dfsek.terra.api.platform.inventory.Item; -import com.dfsek.terra.api.platform.inventory.ItemStack; - -public class ForgeItem implements Item { - private final net.minecraft.item.Item delegate; - - public ForgeItem(net.minecraft.item.Item delegate) { - this.delegate = delegate; - } - - @Override - public net.minecraft.item.Item getHandle() { - return delegate; - } - - @Override - public ItemStack newItemStack(int amount) { - return new ForgeItemStack(new net.minecraft.item.ItemStack(delegate, amount)); - } - - @Override - public double getMaxDurability() { - return delegate.getMaxDamage(); - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/ForgeItemStack.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/ForgeItemStack.java deleted file mode 100644 index 01e186bdb..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/ForgeItemStack.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.dfsek.terra.forge.inventory; - -import com.dfsek.terra.api.platform.inventory.Item; -import com.dfsek.terra.api.platform.inventory.ItemStack; -import com.dfsek.terra.api.platform.inventory.item.ItemMeta; -import com.dfsek.terra.forge.inventory.meta.ForgeDamageable; -import com.dfsek.terra.forge.inventory.meta.ForgeItemMeta; - -public class ForgeItemStack implements ItemStack { - private net.minecraft.item.ItemStack delegate; - - public ForgeItemStack(net.minecraft.item.ItemStack delegate) { - this.delegate = delegate; - } - - @Override - public int getAmount() { - return delegate.getCount(); - } - - @Override - public void setAmount(int i) { - delegate.setCount(i); - } - - @Override - public Item getType() { - return new ForgeItem(delegate.getItem()); - } - - @Override - public ItemMeta getItemMeta() { - if(delegate.isDamageableItem()) return new ForgeDamageable(delegate.copy()); - return new ForgeItemMeta(delegate.copy()); - } - - @Override - public void setItemMeta(ItemMeta meta) { - this.delegate = ((ForgeItemMeta) meta).getHandle(); - } - - @Override - public net.minecraft.item.ItemStack getHandle() { - return delegate; - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/meta/ForgeDamageable.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/meta/ForgeDamageable.java deleted file mode 100644 index 6c0fab95d..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/meta/ForgeDamageable.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.dfsek.terra.forge.inventory.meta; - -import com.dfsek.terra.api.platform.inventory.item.Damageable; -import net.minecraft.item.ItemStack; - -public class ForgeDamageable extends ForgeItemMeta implements Damageable { - public ForgeDamageable(ItemStack delegate) { - super(delegate); - } - - @Override - public int getDamage() { - return delegate.getDamageValue(); - } - - @Override - public void setDamage(int damage) { - delegate.setDamageValue(damage); - } - - @Override - public boolean hasDamage() { - return delegate.isDamaged(); - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/meta/ForgeItemMeta.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/meta/ForgeItemMeta.java deleted file mode 100644 index 7a28ade66..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/inventory/meta/ForgeItemMeta.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.dfsek.terra.forge.inventory.meta; - -import com.dfsek.terra.api.platform.inventory.item.Enchantment; -import com.dfsek.terra.api.platform.inventory.item.ItemMeta; -import com.dfsek.terra.forge.world.ForgeAdapter; -import net.minecraft.command.arguments.NBTCompoundTagArgument; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.CompoundNBT; -import net.minecraft.util.registry.Registry; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -public class ForgeItemMeta implements ItemMeta { - protected final ItemStack delegate; - - public ForgeItemMeta(ItemStack delegate) { - this.delegate = delegate; - } - - @Override - public ItemStack getHandle() { - return delegate; - } - - @Override - public Map getEnchantments() { - if(!delegate.isEnchanted()) return Collections.emptyMap(); - Map map = new HashMap<>(); - - delegate.getEnchantmentTags().forEach(enchantment -> { - CompoundNBT eTag = (CompoundNBT) enchantment; - map.put(ForgeAdapter.adapt(Registry.ENCHANTMENT.byId(eTag.getInt("id"))), eTag.getInt("lvl")); - }); - return map; - } - - @Override - public void addEnchantment(Enchantment enchantment, int level) { - delegate.enchant(ForgeAdapter.adapt(enchantment), level); - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/listener/ClientListener.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/listener/ClientListener.java new file mode 100644 index 000000000..fd4c6cabc --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/listener/ClientListener.java @@ -0,0 +1,50 @@ +package com.dfsek.terra.forge.listener; + +import com.dfsek.terra.api.util.mutable.MutableInteger; +import com.dfsek.terra.config.pack.ConfigPack; +import com.dfsek.terra.forge.TerraForgePlugin; +import com.dfsek.terra.forge.generation.TerraLevelType; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.button.Button; +import net.minecraft.util.text.StringTextComponent; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.client.ForgeWorldTypeScreens; +import net.minecraftforge.common.world.ForgeWorldType; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +@Mod.EventBusSubscriber(value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD) +public class ClientListener { + private static final TerraForgePlugin INSTANCE = TerraForgePlugin.getInstance(); + + @SubscribeEvent + public static void register(FMLClientSetupEvent event) { + INSTANCE.logger().info("Client setup..."); + + ForgeWorldType world = TerraLevelType.FORGE_WORLD_TYPE; + ForgeWorldTypeScreens.registerFactory(world, (returnTo, dimensionGeneratorSettings) -> new Screen(world.getDisplayName()) { + private final MutableInteger num = new MutableInteger(0); + private final List packs = new ArrayList<>(); + private final Button toggle = new Button(0, 25, 120, 20, new StringTextComponent(""), button -> { + num.increment(); + if(num.get() >= packs.size()) num.set(0); + button.setMessage(new StringTextComponent("Pack: " + packs.get(num.get()).getTemplate().getID())); + }); + + @Override + protected void init() { + packs.clear(); + INSTANCE.getConfigRegistry().forEach((Consumer) packs::add); + addButton(new Button(0, 0, 120, 20, new StringTextComponent("Close"), btn -> Minecraft.getInstance().setScreen(returnTo))); + toggle.setMessage(new StringTextComponent("Pack: " + packs.get(num.get()).getTemplate().getID())); + addButton(toggle); + } + }); + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/listener/ForgeListener.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/listener/ForgeListener.java new file mode 100644 index 000000000..35f0d9d63 --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/listener/ForgeListener.java @@ -0,0 +1,81 @@ +package com.dfsek.terra.forge.listener; + +import com.dfsek.terra.api.command.CommandManager; +import com.dfsek.terra.api.command.exception.CommandException; +import com.dfsek.terra.api.platform.CommandSender; +import com.dfsek.terra.api.platform.entity.Entity; +import com.dfsek.terra.forge.TerraForgePlugin; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.builder.ArgumentBuilder; +import com.mojang.brigadier.builder.RequiredArgumentBuilder; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.command.CommandSource; +import net.minecraft.util.text.StringTextComponent; +import net.minecraftforge.event.RegisterCommandsEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal; +import static com.mojang.brigadier.builder.RequiredArgumentBuilder.argument; + +@Mod.EventBusSubscriber(modid = "terra", bus = Mod.EventBusSubscriber.Bus.FORGE) +public class ForgeListener { + private static final TerraForgePlugin INSTANCE = TerraForgePlugin.getInstance(); + + @SuppressWarnings({"unchecked", "rawtypes"}) + @SubscribeEvent + public static void registerCommands(RegisterCommandsEvent event) { + int max = INSTANCE.getManager().getMaxArgumentDepth(); + RequiredArgumentBuilder arg = argument("arg" + (max - 1), StringArgumentType.word()); + for(int i = 0; i < max; i++) { + RequiredArgumentBuilder next = argument("arg" + (max - i - 1), StringArgumentType.word()); + + arg = next.then(assemble(arg, INSTANCE.getManager())); + } + + event.getDispatcher().register(literal("terra").executes(context -> 1).then((ArgumentBuilder) assemble(arg, INSTANCE.getManager()))); + event.getDispatcher().register(literal("te").executes(context -> 1).then((ArgumentBuilder) assemble(arg, INSTANCE.getManager()))); + } + + public static RequiredArgumentBuilder assemble(RequiredArgumentBuilder in, CommandManager manager) { + return in.suggests((context, builder) -> { + List args = parseCommand(context.getInput()); + CommandSender sender = (CommandSender) context.getSource(); + try { + sender = (Entity) context.getSource().getEntityOrException(); + } catch(CommandSyntaxException ignore) { + } + try { + manager.tabComplete(args.remove(0), sender, args).forEach(builder::suggest); + } catch(CommandException e) { + sender.sendMessage(e.getMessage()); + } + return builder.buildFuture(); + }).executes(context -> { + List args = parseCommand(context.getInput()); + try { + CommandSender sender = (CommandSender) context.getSource(); + try { + sender = (Entity) context.getSource().getEntityOrException(); + } catch(CommandSyntaxException ignore) { + } + manager.execute(args.remove(0), sender, args); + } catch(CommandException e) { + context.getSource().sendFailure(new StringTextComponent(e.getMessage())); + } + return 1; + }); + } + + private static List parseCommand(String command) { + if(command.startsWith("/terra ")) command = command.substring("/terra ".length()); + else if(command.startsWith("/te ")) command = command.substring("/te ".length()); + List c = new ArrayList<>(Arrays.asList(command.split(" "))); + if(command.endsWith(" ")) c.add(""); + return c; + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/listener/RegistryListener.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/listener/RegistryListener.java new file mode 100644 index 000000000..726f22e08 --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/listener/RegistryListener.java @@ -0,0 +1,33 @@ +package com.dfsek.terra.forge.listener; + +import com.dfsek.terra.forge.ForgeUtil; +import com.dfsek.terra.forge.TerraForgePlugin; +import com.dfsek.terra.forge.generation.TerraLevelType; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.feature.Feature; +import net.minecraftforge.common.world.ForgeWorldType; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) +public class RegistryListener { + private static final TerraForgePlugin INSTANCE = TerraForgePlugin.getInstance(); + + @SubscribeEvent + public static void registerLevels(RegistryEvent.Register event) { + INSTANCE.logger().info("Registering level types..."); + event.getRegistry().register(TerraLevelType.FORGE_WORLD_TYPE); + } + + @SubscribeEvent + public static void register(RegistryEvent.Register event) { + INSTANCE.setup(); // Setup now because we need the biomes, and this event happens after blocks n stuff + INSTANCE.getConfigRegistry().forEach(pack -> pack.getBiomeRegistry().forEach((id, biome) -> event.getRegistry().register(ForgeUtil.createBiome(biome)))); // Register all Terra biomes. + } + + @SubscribeEvent + public static void registerPop(RegistryEvent.Register> event) { + event.getRegistry().register(TerraForgePlugin.POPULATOR_FEATURE); + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/DimensionGeneratorSettingsMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/DimensionGeneratorSettingsMixin.java new file mode 100644 index 000000000..ca899217a --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/DimensionGeneratorSettingsMixin.java @@ -0,0 +1,64 @@ +package com.dfsek.terra.forge.mixin; + +import com.dfsek.terra.config.pack.ConfigPack; +import com.dfsek.terra.forge.TerraForgePlugin; +import com.dfsek.terra.forge.generation.ForgeChunkGeneratorWrapper; +import com.dfsek.terra.forge.generation.TerraBiomeSource; +import com.google.common.base.MoreObjects; +import net.minecraft.util.registry.DynamicRegistries; +import net.minecraft.util.registry.Registry; +import net.minecraft.util.registry.SimpleRegistry; +import net.minecraft.world.Dimension; +import net.minecraft.world.DimensionType; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.DimensionSettings; +import net.minecraft.world.gen.settings.DimensionGeneratorSettings; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Properties; +import java.util.Random; + +@Mixin(DimensionGeneratorSettings.class) +public abstract class DimensionGeneratorSettingsMixin { + @Inject(method = "create(Lnet/minecraft/util/registry/DynamicRegistries;Ljava/util/Properties;)Lnet/minecraft/world/gen/settings/DimensionGeneratorSettings;", at = @At("HEAD"), cancellable = true) + private static void fromProperties(DynamicRegistries dynamicRegistries, Properties properties, CallbackInfoReturnable cir) { + if(properties.get("level-type") == null) { + return; + } + + String prop = properties.get("level-type").toString().trim(); + if(prop.startsWith("Terra")) { + String seed = (String) MoreObjects.firstNonNull(properties.get("level-seed"), ""); + long l = new Random().nextLong(); + if(!seed.isEmpty()) { + try { + long m = Long.parseLong(seed); + if(m != 0L) { + l = m; + } + } catch(NumberFormatException exception) { + l = seed.hashCode(); + } + } + + String generate_structures = (String) properties.get("generate-structures"); + boolean generateStructures = generate_structures == null || Boolean.parseBoolean(generate_structures); + Registry dimensionTypes = dynamicRegistries.registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY); + Registry biomes = dynamicRegistries.registryOrThrow(Registry.BIOME_REGISTRY); + Registry chunkGeneratorSettings = dynamicRegistries.registryOrThrow(Registry.NOISE_GENERATOR_SETTINGS_REGISTRY); + SimpleRegistry dimensionOptions = DimensionType.defaultDimensions(dimensionTypes, biomes, chunkGeneratorSettings, l); + + prop = prop.substring(prop.indexOf(":") + 1); + + ConfigPack pack = TerraForgePlugin.getInstance().getConfigRegistry().get(prop); + + if(pack == null) throw new IllegalArgumentException("No such pack " + prop); + + TerraForgePlugin.getInstance().logger().info("Using config pack " + pack.getTemplate().getID()); + cir.setReturnValue(new DimensionGeneratorSettings(l, generateStructures, false, DimensionGeneratorSettings.withOverworld(dimensionTypes, dimensionOptions, new ForgeChunkGeneratorWrapper(new TerraBiomeSource(biomes, l, pack), l, pack)))); + } + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/access/AbstractSpawnerAccessor.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/access/AbstractSpawnerAccessor.java new file mode 100644 index 000000000..5783c350f --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/access/AbstractSpawnerAccessor.java @@ -0,0 +1,12 @@ +package com.dfsek.terra.forge.mixin.access; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.spawner.AbstractSpawner; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(AbstractSpawner.class) +public interface AbstractSpawnerAccessor { + @Invoker("getEntityId") + ResourceLocation callGetEntityId(); +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/BiomeMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/BiomeMixin.java new file mode 100644 index 000000000..317893290 --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/BiomeMixin.java @@ -0,0 +1,14 @@ +package com.dfsek.terra.forge.mixin.implementations; + +import net.minecraft.world.biome.Biome; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(Biome.class) +@Implements(@Interface(iface = com.dfsek.terra.api.platform.world.Biome.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class BiomeMixin { + public Object terra$getHandle() { + return this; + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/ChunkGeneratorMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/ChunkGeneratorMixin.java new file mode 100644 index 000000000..14fa0e2c5 --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/ChunkGeneratorMixin.java @@ -0,0 +1,14 @@ +package com.dfsek.terra.forge.mixin.implementations; + +import net.minecraft.world.gen.ChunkGenerator; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(ChunkGenerator.class) +@Implements(@Interface(iface = com.dfsek.terra.api.platform.world.generator.ChunkGenerator.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class ChunkGeneratorMixin { + public Object terra$getHandle() { + return this; + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/ConfiguredFeatureMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/ConfiguredFeatureMixin.java new file mode 100644 index 000000000..f0e1d0b4a --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/ConfiguredFeatureMixin.java @@ -0,0 +1,40 @@ +package com.dfsek.terra.forge.mixin.implementations; + +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 com.dfsek.terra.forge.TerraForgePlugin; +import com.dfsek.terra.profiler.ProfileFrame; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.ISeedReader; +import net.minecraft.world.gen.ChunkGenerator; +import net.minecraft.world.gen.feature.ConfiguredFeature; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.Random; + +@Mixin(ConfiguredFeature.class) +@Implements(@Interface(iface = Tree.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class ConfiguredFeatureMixin { + + @Shadow + public abstract boolean place(ISeedReader p_242765_1_, ChunkGenerator p_242765_2_, Random p_242765_3_, BlockPos p_242765_4_); + + @SuppressWarnings({"try"}) + public boolean terra$plant(Location l, Random r) { + try(ProfileFrame ignore = TerraForgePlugin.getInstance().getProfiler().profile("forge_tree")) { + ISeedReader world = ((ISeedReader) l.getWorld()); + ChunkGenerator generatorWrapper = (ChunkGenerator) l.getWorld().getGenerator(); + return place(world, generatorWrapper, r, new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ())); + } + } + + public MaterialSet terra$getSpawnable() { + return MaterialSet.get(TerraForgePlugin.getInstance().getWorldHandle().createBlockData("minecraft:grass_block"), + TerraForgePlugin.getInstance().getWorldHandle().createBlockData("minecraft:podzol"), + TerraForgePlugin.getInstance().getWorldHandle().createBlockData("minecraft:mycelium")); + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/block/BlockMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/block/BlockMixin.java new file mode 100644 index 000000000..ee4bf13ed --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/block/BlockMixin.java @@ -0,0 +1,36 @@ +package com.dfsek.terra.forge.mixin.implementations.block; + +import com.dfsek.terra.api.platform.block.BlockData; +import com.dfsek.terra.api.platform.block.BlockType; +import com.dfsek.terra.forge.ForgeAdapter; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(Block.class) +@Implements(@Interface(iface = BlockType.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class BlockMixin { + @Shadow + private BlockState defaultBlockState; + + public Object terra$getHandle() { + return this; + } + + public BlockData terra$getDefaultData() { + return ForgeAdapter.adapt(defaultBlockState); + } + + public boolean terra$isSolid() { + return defaultBlockState.canOcclude(); + } + + @SuppressWarnings("ConstantConditions") + public boolean terra$isWater() { + return ((Object) this) == Blocks.WATER; + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/block/TileEntityMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/block/TileEntityMixin.java new file mode 100644 index 000000000..2f7bd3918 --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/block/TileEntityMixin.java @@ -0,0 +1,63 @@ +package com.dfsek.terra.forge.mixin.implementations.block; + +import com.dfsek.terra.api.platform.block.Block; +import com.dfsek.terra.api.platform.block.BlockData; +import com.dfsek.terra.api.platform.block.state.BlockState; +import com.dfsek.terra.forge.ForgeAdapter; +import com.dfsek.terra.forge.block.ForgeBlock; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import javax.annotation.Nullable; + +@Mixin(TileEntity.class) +@Implements(@Interface(iface = BlockState.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class TileEntityMixin { + @Shadow + protected BlockPos worldPosition; + + @Shadow + @Nullable + protected World level; + + @Shadow + @Nullable + private net.minecraft.block.BlockState blockState; + + @Shadow + public abstract boolean hasLevel(); + + public Object terra$getHandle() { + return this; + } + + public Block terra$getBlock() { + return new ForgeBlock(worldPosition, level); + } + + public int terra$getX() { + return worldPosition.getX(); + } + + public int terra$getY() { + return worldPosition.getY(); + } + + public int terra$getZ() { + return worldPosition.getZ(); + } + + public BlockData terra$getBlockData() { + return ForgeAdapter.adapt(blockState); + } + + public boolean terra$update(boolean applyPhysics) { + if(hasLevel()) level.getChunk(worldPosition).setBlockEntity(worldPosition, (TileEntity) (Object) this); + return true; + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/block/state/LockableLootTileEntityMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/block/state/LockableLootTileEntityMixin.java new file mode 100644 index 000000000..977309616 --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/block/state/LockableLootTileEntityMixin.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.forge.mixin.implementations.block.state; + +import com.dfsek.terra.api.platform.block.state.Container; +import com.dfsek.terra.api.platform.inventory.Inventory; +import com.dfsek.terra.forge.mixin.implementations.block.TileEntityMixin; +import net.minecraft.tileentity.LockableLootTileEntity; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(LockableLootTileEntity.class) +@Implements(@Interface(iface = Container.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class LockableLootTileEntityMixin extends TileEntityMixin { + public Inventory terra$getInventory() { + return (Inventory) this; + } + + public Object terra$getHandle() { + return this; + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/block/state/MobSpawnerTileEntityMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/block/state/MobSpawnerTileEntityMixin.java new file mode 100644 index 000000000..1f73b7583 --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/block/state/MobSpawnerTileEntityMixin.java @@ -0,0 +1,120 @@ +package com.dfsek.terra.forge.mixin.implementations.block.state; + +import com.dfsek.terra.api.platform.block.state.MobSpawner; +import com.dfsek.terra.api.platform.block.state.SerialState; +import com.dfsek.terra.api.platform.entity.EntityType; +import com.dfsek.terra.forge.TerraForgePlugin; +import com.dfsek.terra.forge.mixin.access.AbstractSpawnerAccessor; +import com.dfsek.terra.forge.mixin.implementations.block.TileEntityMixin; +import net.minecraft.tileentity.MobSpawnerTileEntity; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.spawner.AbstractSpawner; +import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(MobSpawnerTileEntity.class) +@Implements(@Interface(iface = MobSpawner.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class MobSpawnerTileEntityMixin extends TileEntityMixin { + @Shadow + public abstract AbstractSpawner getSpawner(); + + public EntityType terra$getSpawnedType() { + return (EntityType) Registry.ENTITY_TYPE.get(((AbstractSpawnerAccessor) getSpawner()).callGetEntityId()); + } + + public void terra$setSpawnedType(@NotNull EntityType creatureType) { + getSpawner().setEntityId((net.minecraft.entity.EntityType) creatureType); + } + + public int terra$getDelay() { + return 0; + } + + public void terra$setDelay(int delay) { + + } + + public int terra$getMinSpawnDelay() { + return 0; + } + + public void terra$setMinSpawnDelay(int delay) { + + } + + public int terra$getMaxSpawnDelay() { + return 0; + } + + public void terra$setMaxSpawnDelay(int delay) { + + } + + public int terra$getSpawnCount() { + return 0; + } + + public void terra$setSpawnCount(int spawnCount) { + + } + + public int terra$getMaxNearbyEntities() { + return 0; + } + + public void terra$setMaxNearbyEntities(int maxNearbyEntities) { + + } + + public int terra$getRequiredPlayerRange() { + return 0; + } + + public void terra$setRequiredPlayerRange(int requiredPlayerRange) { + + } + + public int terra$getSpawnRange() { + return 0; + } + + public void terra$setSpawnRange(int spawnRange) { + + } + + public void terra$applyState(String state) { + SerialState.parse(state).forEach((k, v) -> { + switch(k) { + case "type": + terra$setSpawnedType(TerraForgePlugin.getInstance().getWorldHandle().getEntity(v)); + return; + case "delay": + terra$setDelay(Integer.parseInt(v)); + return; + case "min_delay": + terra$setMinSpawnDelay(Integer.parseInt(v)); + return; + case "max_delay": + terra$setMaxSpawnDelay(Integer.parseInt(v)); + return; + case "spawn_count": + terra$setSpawnCount(Integer.parseInt(v)); + return; + case "spawn_range": + terra$setSpawnRange(Integer.parseInt(v)); + return; + case "max_nearby": + terra$setMaxNearbyEntities(Integer.parseInt(v)); + return; + case "required_player_range": + terra$setRequiredPlayerRange(Integer.parseInt(v)); + return; + default: + throw new IllegalArgumentException("Invalid property: " + k); + } + }); + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/block/state/SignTileEntityMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/block/state/SignTileEntityMixin.java new file mode 100644 index 000000000..40ec0368c --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/block/state/SignTileEntityMixin.java @@ -0,0 +1,48 @@ +package com.dfsek.terra.forge.mixin.implementations.block.state; + +import com.dfsek.terra.api.platform.block.state.SerialState; +import com.dfsek.terra.api.platform.block.state.Sign; +import net.minecraft.tileentity.SignTileEntity; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.StringTextComponent; +import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(SignTileEntity.class) +@Implements(@Interface(iface = Sign.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class SignTileEntityMixin { + @Shadow + @Final + private ITextComponent[] messages; + + @Shadow + public abstract void setMessage(int p_212365_1_, ITextComponent p_212365_2_); + + public @NotNull String[] terra$getLines() { + String[] lines = new String[messages.length]; + for(int i = 0; i < messages.length; i++) { + lines[i] = messages[i].getString(); + } + return lines; + } + + public @NotNull String terra$getLine(int index) throws IndexOutOfBoundsException { + + return messages[index].getString(); + } + + public void terra$setLine(int index, @NotNull String line) throws IndexOutOfBoundsException { + setMessage(index, new StringTextComponent(line)); + } + + public void terra$applyState(String state) { + SerialState.parse(state).forEach((k, v) -> { + if(!k.startsWith("text")) throw new IllegalArgumentException("Invalid property: " + k); + terra$setLine(Integer.parseInt(k.substring(4)), v); + }); + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/chunk/ChunkMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/chunk/ChunkMixin.java new file mode 100644 index 000000000..6d93b8cef --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/chunk/ChunkMixin.java @@ -0,0 +1,54 @@ +package com.dfsek.terra.forge.mixin.implementations.chunk; + +import com.dfsek.terra.api.platform.block.Block; +import com.dfsek.terra.api.platform.block.BlockData; +import com.dfsek.terra.api.platform.world.Chunk; +import com.dfsek.terra.api.platform.world.World; +import com.dfsek.terra.forge.block.ForgeBlock; +import com.dfsek.terra.forge.block.ForgeBlockData; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.IChunk; +import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(net.minecraft.world.chunk.Chunk.class) +@Implements(@Interface(iface = Chunk.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class ChunkMixin { + + @Shadow + @Final + private net.minecraft.world.World level; + + public int terra$getX() { + return ((IChunk) this).getPos().x; + } + + public int terra$getZ() { + return ((IChunk) this).getPos().z; + } + + public World terra$getWorld() { + return (World) level; + } + + public Block terra$getBlock(int x, int y, int z) { + BlockPos pos = new BlockPos(x + (terra$getX() << 4), y, z + (terra$getZ() << 4)); + return new ForgeBlock(pos, level); + } + + public @NotNull BlockData terra$getBlockData(int x, int y, int z) { + return terra$getBlock(x, y, z).getBlockData(); + } + + public void terra$setBlock(int x, int y, int z, @NotNull BlockData blockData) { + ((IChunk) this).setBlockState(new BlockPos(x, y, z), ((ForgeBlockData) blockData).getHandle(), false); + } + + public Object terra$getHandle() { + return this; + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/chunk/WorldGenRegionMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/chunk/WorldGenRegionMixin.java new file mode 100644 index 000000000..7844a9637 --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/chunk/WorldGenRegionMixin.java @@ -0,0 +1,57 @@ +package com.dfsek.terra.forge.mixin.implementations.chunk; + +import com.dfsek.terra.api.platform.block.Block; +import com.dfsek.terra.api.platform.block.BlockData; +import com.dfsek.terra.api.platform.world.Chunk; +import com.dfsek.terra.api.platform.world.World; +import com.dfsek.terra.forge.block.ForgeBlock; +import com.dfsek.terra.forge.block.ForgeBlockData; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.gen.WorldGenRegion; +import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(WorldGenRegion.class) +@Implements(@Interface(iface = Chunk.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class WorldGenRegionMixin { + @Final + @Shadow + private int x; + + @Final + @Shadow + private int z; + + public int terra$getX() { + return x; + } + + public int terra$getZ() { + return z; + } + + public World terra$getWorld() { + return (World) this; + } + + public Block terra$getBlock(int x, int y, int z) { + BlockPos pos = new BlockPos(x + (this.x << 4), y, z + (this.z << 4)); + return new ForgeBlock(pos, (WorldGenRegion) (Object) this); + } + + public @NotNull BlockData terra$getBlockData(int x, int y, int z) { + return terra$getBlock(x, y, z).getBlockData(); + } + + public void terra$setBlock(int x, int y, int z, @NotNull BlockData blockData) { + ((WorldGenRegion) (Object) this).setBlock(new BlockPos(x + (this.x << 4), y, z + (this.z << 4)), ((ForgeBlockData) blockData).getHandle(), 0); + } + + public Object terra$getHandle() { + return this; + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/chunk/data/ChunkPrimerMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/chunk/data/ChunkPrimerMixin.java new file mode 100644 index 000000000..5e5404406 --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/chunk/data/ChunkPrimerMixin.java @@ -0,0 +1,37 @@ +package com.dfsek.terra.forge.mixin.implementations.chunk.data; + +import com.dfsek.terra.api.platform.block.BlockData; +import com.dfsek.terra.api.platform.world.generator.ChunkData; +import com.dfsek.terra.forge.block.ForgeBlockData; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.ChunkPrimer; +import net.minecraft.world.chunk.IChunk; +import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(ChunkPrimer.class) +@Implements(@Interface(iface = ChunkData.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class ChunkPrimerMixin { + @Shadow + public abstract BlockState getBlockState(BlockPos pos); + + public @NotNull BlockData terra$getBlockData(int x, int y, int z) { + return new ForgeBlockData(getBlockState(new BlockPos(x, y, z))); + } + + public void terra$setBlock(int x, int y, int z, @NotNull BlockData blockData) { + ((IChunk) this).setBlockState(new BlockPos(x, y, z), ((ForgeBlockData) blockData).getHandle(), false); + } + + public Object terra$getHandle() { + return this; + } + + public int terra$getMaxHeight() { + return 255; // TODO: 1.17 - Implement dynamic height. + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/entity/CommandSourceMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/entity/CommandSourceMixin.java new file mode 100644 index 000000000..83df7b48c --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/entity/CommandSourceMixin.java @@ -0,0 +1,25 @@ +package com.dfsek.terra.forge.mixin.implementations.entity; + +import com.dfsek.terra.api.platform.CommandSender; +import net.minecraft.command.CommandSource; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.StringTextComponent; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(CommandSource.class) +@Implements(@Interface(iface = CommandSender.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class CommandSourceMixin { + @Shadow + public abstract void sendSuccess(ITextComponent p_197030_1_, boolean p_197030_2_); + + public void terra$sendMessage(String message) { + sendSuccess(new StringTextComponent(message), true); + } + + public Object terra$getHandle() { + return this; + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/entity/EntityMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/entity/EntityMixin.java new file mode 100644 index 000000000..7cc684c35 --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/entity/EntityMixin.java @@ -0,0 +1,52 @@ +package com.dfsek.terra.forge.mixin.implementations.entity; + +import com.dfsek.terra.api.math.vector.Location; +import com.dfsek.terra.api.platform.world.World; +import com.dfsek.terra.forge.ForgeAdapter; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.StringTextComponent; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.UUID; + +@Mixin(Entity.class) +@Implements(@Interface(iface = com.dfsek.terra.api.platform.entity.Entity.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class EntityMixin { + @Shadow + public net.minecraft.world.World level; + + @Shadow + private BlockPos blockPosition; + + @Shadow + public abstract void teleportTo(double destX, double destY, double destZ); + + + @Shadow + public abstract void sendMessage(ITextComponent p_145747_1_, UUID p_145747_2_); + + public Object terra$getHandle() { + return this; + } + + public Location terra$getLocation() { + return new Location((World) level, ForgeAdapter.adapt(blockPosition)); + } + + public void terra$setLocation(Location location) { + teleportTo(location.getX(), location.getY(), location.getZ()); + } + + public World terra$getWorld() { + return (World) level; + } + + public void terra$sendMessage(String message) { + sendMessage(new StringTextComponent(message), UUID.randomUUID()); // TODO: look into how this actually works and make it less jank + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/entity/EntityTypeMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/entity/EntityTypeMixin.java new file mode 100644 index 000000000..e7bb15a70 --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/entity/EntityTypeMixin.java @@ -0,0 +1,14 @@ +package com.dfsek.terra.forge.mixin.implementations.entity; + +import net.minecraft.entity.EntityType; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(EntityType.class) +@Implements(@Interface(iface = com.dfsek.terra.api.platform.entity.EntityType.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class EntityTypeMixin { + public Object terra$getHandle() { + return this; + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/entity/PlayerEntityMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/entity/PlayerEntityMixin.java new file mode 100644 index 000000000..7ee5d6731 --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/entity/PlayerEntityMixin.java @@ -0,0 +1,13 @@ +package com.dfsek.terra.forge.mixin.implementations.entity; + +import com.dfsek.terra.api.platform.entity.Player; +import net.minecraft.entity.player.PlayerEntity; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(PlayerEntity.class) +@Implements(@Interface(iface = Player.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class PlayerEntityMixin extends EntityMixin { + +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/inventory/LockableTileEntityMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/inventory/LockableTileEntityMixin.java new file mode 100644 index 000000000..06a279ed3 --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/inventory/LockableTileEntityMixin.java @@ -0,0 +1,32 @@ +package com.dfsek.terra.forge.mixin.implementations.inventory; + +import com.dfsek.terra.api.platform.inventory.Inventory; +import com.dfsek.terra.api.platform.inventory.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.tileentity.LockableTileEntity; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(LockableTileEntity.class) +@Implements(@Interface(iface = Inventory.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public class LockableTileEntityMixin { + public Object terra$getHandle() { + return this; + } + + public int terra$getSize() { + return ((LockableTileEntity) (Object) this).getContainerSize(); + } + + @SuppressWarnings("ConstantConditions") + public ItemStack terra$getItem(int slot) { + net.minecraft.item.ItemStack itemStack = ((LockableTileEntity) (Object) this).getItem(slot); + return itemStack.getItem() == Items.AIR ? null : (ItemStack) (Object) itemStack; + } + + @SuppressWarnings("ConstantConditions") + public void terra$setItem(int slot, ItemStack newStack) { + ((LockableTileEntity) (Object) this).setItem(slot, (net.minecraft.item.ItemStack) (Object) newStack); + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/inventory/item/ItemMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/inventory/item/ItemMixin.java new file mode 100644 index 000000000..a7efd1706 --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/inventory/item/ItemMixin.java @@ -0,0 +1,28 @@ +package com.dfsek.terra.forge.mixin.implementations.inventory.item; + +import com.dfsek.terra.api.platform.inventory.ItemStack; +import net.minecraft.item.Item; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(Item.class) +@Implements(@Interface(iface = com.dfsek.terra.api.platform.inventory.Item.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class ItemMixin { + @Shadow + public abstract int getMaxDamage(); + + public Object terra$getHandle() { + return this; + } + + @SuppressWarnings("ConstantConditions") + public ItemStack terra$newItemStack(int amount) { + return (ItemStack) (Object) new net.minecraft.item.ItemStack((Item) (Object) this, amount); + } + + public double terra$getMaxDurability() { + return getMaxDamage(); + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/inventory/item/ItemStackMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/inventory/item/ItemStackMixin.java new file mode 100644 index 000000000..714dcab02 --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/inventory/item/ItemStackMixin.java @@ -0,0 +1,62 @@ +package com.dfsek.terra.forge.mixin.implementations.inventory.item; + +import com.dfsek.terra.api.platform.inventory.Item; +import com.dfsek.terra.api.platform.inventory.item.ItemMeta; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Intrinsic; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(ItemStack.class) +@Implements(@Interface(iface = com.dfsek.terra.api.platform.inventory.ItemStack.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class ItemStackMixin { + @Shadow + public abstract int getCount(); + + @Shadow + public abstract void setCount(int count); + + @Shadow + public abstract net.minecraft.item.Item getItem(); + + + @Shadow + public abstract boolean isDamageableItem(); + + @Shadow + public abstract void setTag(@Nullable CompoundNBT p_77982_1_); + + public int terra$getAmount() { + return getCount(); + } + + public void terra$setAmount(int i) { + setCount(i); + } + + public Item terra$getType() { + return (Item) getItem(); + } + + public ItemMeta terra$getItemMeta() { + return (ItemMeta) this; + } + + @SuppressWarnings("ConstantConditions") + public void terra$setItemMeta(ItemMeta meta) { + setTag(((ItemStack) (Object) meta).getTag()); + } + + public Object terra$getHandle() { + return this; + } + + @Intrinsic + public boolean terra$isDamageable() { + return isDamageableItem(); + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/inventory/meta/EnchantmentMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/inventory/meta/EnchantmentMixin.java new file mode 100644 index 000000000..69bbfecaa --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/inventory/meta/EnchantmentMixin.java @@ -0,0 +1,39 @@ +package com.dfsek.terra.forge.mixin.implementations.inventory.meta; + +import com.dfsek.terra.api.platform.inventory.ItemStack; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.util.registry.Registry; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.Objects; + +@Mixin(Enchantment.class) +@Implements(@Interface(iface = com.dfsek.terra.api.platform.inventory.item.Enchantment.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class EnchantmentMixin { + + @Shadow + public abstract boolean isCompatibleWith(Enchantment p_191560_1_); + + @Shadow + public abstract boolean canEnchant(net.minecraft.item.ItemStack p_92089_1_); + + public Object terra$getHandle() { + return this; + } + + @SuppressWarnings("ConstantConditions") + public boolean terra$canEnchantItem(ItemStack itemStack) { + return canEnchant((net.minecraft.item.ItemStack) (Object) itemStack); + } + + public String terra$getID() { + return Objects.requireNonNull(Registry.ENCHANTMENT.getId((Enchantment) (Object) this)).toString(); + } + + public boolean terra$conflictsWith(com.dfsek.terra.api.platform.inventory.item.Enchantment other) { + return !isCompatibleWith((Enchantment) other); + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/inventory/meta/ItemStackDamageableMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/inventory/meta/ItemStackDamageableMixin.java new file mode 100644 index 000000000..8a1b438f5 --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/inventory/meta/ItemStackDamageableMixin.java @@ -0,0 +1,36 @@ +package com.dfsek.terra.forge.mixin.implementations.inventory.meta; + +import com.dfsek.terra.api.platform.inventory.item.Damageable; +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Intrinsic; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(ItemStack.class) +@Implements(@Interface(iface = Damageable.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class ItemStackDamageableMixin { + @Shadow + public abstract boolean isDamaged(); + + @Shadow + public abstract int getDamageValue(); + + @Shadow + public abstract void setDamageValue(int p_196085_1_); + + public boolean terra$hasDamage() { + return isDamaged(); + } + + @Intrinsic + public void terra$setDamage(int damage) { + setDamageValue(damage); + } + + @Intrinsic + public int terra$getDamage() { + return getDamageValue(); + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/inventory/meta/ItemStackMetaMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/inventory/meta/ItemStackMetaMixin.java new file mode 100644 index 000000000..aa9b2a41b --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/inventory/meta/ItemStackMetaMixin.java @@ -0,0 +1,50 @@ +package com.dfsek.terra.forge.mixin.implementations.inventory.meta; + +import com.dfsek.terra.api.platform.inventory.item.Enchantment; +import com.dfsek.terra.api.platform.inventory.item.ItemMeta; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.ListNBT; +import net.minecraft.util.registry.Registry; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Intrinsic; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +@Mixin(ItemStack.class) +@Implements(@Interface(iface = ItemMeta.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class ItemStackMetaMixin { + @Shadow + public abstract ListNBT getEnchantmentTags(); + + @Shadow + public abstract boolean isEnchanted(); + + @Shadow + public abstract void enchant(net.minecraft.enchantment.Enchantment p_77966_1_, int p_77966_2_); + + public Object terra$getHandle() { + return this; + } + + @Intrinsic(displace = true) + public Map terra$getEnchantments() { + if(!isEnchanted()) return Collections.emptyMap(); + Map map = new HashMap<>(); + + getEnchantmentTags().forEach(enchantment -> { + CompoundNBT eTag = (CompoundNBT) enchantment; + map.put((Enchantment) Registry.ENCHANTMENT.byId(eTag.getInt("id")), eTag.getInt("lvl")); + }); + return map; + } + + public void terra$addEnchantment(Enchantment enchantment, int level) { + enchant((net.minecraft.enchantment.Enchantment) enchantment, level); + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/package-info.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/package-info.java new file mode 100644 index 000000000..0fae9920e --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/package-info.java @@ -0,0 +1,5 @@ +/** + * Mixins in this package implement Terra + * interfaces in Minecraft classes. + */ +package com.dfsek.terra.forge.mixin.implementations; \ No newline at end of file diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/world/ServerWorldMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/world/ServerWorldMixin.java new file mode 100644 index 000000000..024b4970d --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/world/ServerWorldMixin.java @@ -0,0 +1,86 @@ +package com.dfsek.terra.forge.mixin.implementations.world; + +import com.dfsek.terra.api.math.vector.Location; +import com.dfsek.terra.api.platform.block.Block; +import com.dfsek.terra.api.platform.entity.Entity; +import com.dfsek.terra.api.platform.entity.EntityType; +import com.dfsek.terra.api.platform.world.Chunk; +import com.dfsek.terra.api.platform.world.World; +import com.dfsek.terra.api.platform.world.generator.ChunkGenerator; +import com.dfsek.terra.api.platform.world.generator.GeneratorWrapper; +import com.dfsek.terra.api.world.generation.TerraChunkGenerator; +import com.dfsek.terra.forge.block.ForgeBlock; +import com.dfsek.terra.forge.generation.ForgeChunkGeneratorWrapper; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IServerWorld; +import net.minecraft.world.server.ServerWorld; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Intrinsic; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(ServerWorld.class) +@Implements(@Interface(iface = World.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class ServerWorldMixin { + @Shadow + public abstract long getSeed(); + + public int terra$getMaxHeight() { + return ((ServerWorld) (Object) this).getMaxBuildHeight(); + } + + public ChunkGenerator terra$getGenerator() { + return (ChunkGenerator) ((ServerWorld) (Object) this).getChunkSource().getGenerator(); + } + + public Chunk terra$getChunkAt(int x, int z) { + return (Chunk) ((ServerWorld) (Object) this).getChunk(x, z); + } + + public Block terra$getBlockAt(int x, int y, int z) { + return new ForgeBlock(new BlockPos(x, y, z), ((ServerWorld) (Object) this)); + } + + public Entity terra$spawnEntity(Location location, EntityType entityType) { + net.minecraft.entity.Entity entity = ((net.minecraft.entity.EntityType) entityType).create(((ServerWorld) (Object) this)); + entity.setPos(location.getX(), location.getY(), location.getZ()); + ((ServerWorld) (Object) this).addFreshEntity(entity); + return (Entity) entity; + } + + @Intrinsic + public long terra$getSeed() { + return getSeed(); + } + + public int terra$getMinHeight() { + return 0; + } + + public Object terra$getHandle() { + return this; + } + + public boolean terra$isTerraWorld() { + return terra$getGenerator() instanceof GeneratorWrapper; + } + + public TerraChunkGenerator terra$getTerraGenerator() { + return ((ForgeChunkGeneratorWrapper) terra$getGenerator()).getHandle(); + } + + /** + * Overridden in the same manner as {@link WorldGenRegionMixin#hashCode()} + * + * @param other Another object + * @return Whether this world is the same as other. + * @see WorldGenRegionMixin#hashCode() + */ + @SuppressWarnings("ConstantConditions") + @Override + public boolean equals(Object other) { + if(!(other instanceof IServerWorld)) return false; + return (IServerWorld) this == (((IServerWorld) other).getLevel()); + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/world/WorldGenRegionMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/world/WorldGenRegionMixin.java new file mode 100644 index 000000000..0b162b591 --- /dev/null +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/implementations/world/WorldGenRegionMixin.java @@ -0,0 +1,108 @@ +package com.dfsek.terra.forge.mixin.implementations.world; + +import com.dfsek.terra.api.math.vector.Location; +import com.dfsek.terra.api.platform.block.Block; +import com.dfsek.terra.api.platform.entity.Entity; +import com.dfsek.terra.api.platform.entity.EntityType; +import com.dfsek.terra.api.platform.world.Chunk; +import com.dfsek.terra.api.platform.world.World; +import com.dfsek.terra.api.platform.world.generator.ChunkGenerator; +import com.dfsek.terra.api.platform.world.generator.GeneratorWrapper; +import com.dfsek.terra.api.world.generation.TerraChunkGenerator; +import com.dfsek.terra.forge.block.ForgeBlock; +import com.dfsek.terra.forge.generation.ForgeChunkGeneratorWrapper; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.gen.WorldGenRegion; +import net.minecraft.world.server.ServerWorld; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Intrinsic; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(WorldGenRegion.class) +@Implements(@Interface(iface = World.class, prefix = "terra$", remap = Interface.Remap.NONE)) +public abstract class WorldGenRegionMixin { + @Shadow + @Final + private ServerWorld level; + + @Shadow + @Final + private long seed; + + public int terra$getMaxHeight() { + return ((WorldGenRegion) (Object) this).getMaxBuildHeight(); + } + + @SuppressWarnings("deprecation") + public ChunkGenerator terra$getGenerator() { + return (ChunkGenerator) ((WorldGenRegion) (Object) this).getLevel().getChunkSource().getGenerator(); + } + + public Chunk terra$getChunkAt(int x, int z) { + return (Chunk) ((WorldGenRegion) (Object) this).getChunk(x, z); + } + + public Block terra$getBlockAt(int x, int y, int z) { + return new ForgeBlock(new BlockPos(x, y, z), ((WorldGenRegion) (Object) this)); + } + + @SuppressWarnings("deprecation") + public Entity terra$spawnEntity(Location location, EntityType entityType) { + net.minecraft.entity.Entity entity = ((net.minecraft.entity.EntityType) entityType).create(((WorldGenRegion) (Object) this).getLevel()); + entity.setPos(location.getX(), location.getY(), location.getZ()); + ((WorldGenRegion) (Object) this).addFreshEntity(entity); + return (Entity) entity; + } + + @Intrinsic + public long terra$getSeed() { + return seed; + } + + public int terra$getMinHeight() { + return 0; + } + + public Object terra$getHandle() { + return this; + } + + public boolean terra$isTerraWorld() { + return terra$getGenerator() instanceof GeneratorWrapper; + } + + public TerraChunkGenerator terra$getTerraGenerator() { + return ((ForgeChunkGeneratorWrapper) terra$getGenerator()).getHandle(); + } + + /** + * We need regions delegating to the same world + * to have the same hashcode. This + * minimizes cache misses. + *

+ * This is sort of jank, but shouldn't(tm) + * break any other mods, unless they're doing + * something they really shouldn't, since + * ChunkRegions are not supposed to persist. + */ + @Override + public int hashCode() { + return level.hashCode(); + } + + /** + * Overridden in the same manner as {@link #hashCode()} + * + * @param other Another object + * @return Whether this world is the same as other. + * @see #hashCode() + */ + @Override + public boolean equals(Object other) { + if(!(other instanceof WorldGenRegion)) return false; + return level.equals(((WorldGenRegion) other).getLevel()); + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/ForgeAdapter.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/ForgeAdapter.java deleted file mode 100644 index 1d34cdf03..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/ForgeAdapter.java +++ /dev/null @@ -1,128 +0,0 @@ -package com.dfsek.terra.forge.world; - -import com.dfsek.terra.api.math.vector.Vector3; -import com.dfsek.terra.api.platform.CommandSender; -import com.dfsek.terra.api.platform.block.BlockFace; -import com.dfsek.terra.api.platform.block.BlockType; -import com.dfsek.terra.api.platform.entity.EntityType; -import com.dfsek.terra.api.platform.inventory.item.Enchantment; -import com.dfsek.terra.forge.inventory.ForgeEnchantment; -import com.dfsek.terra.forge.inventory.ForgeItem; -import com.dfsek.terra.forge.inventory.ForgeItemStack; -import com.dfsek.terra.forge.world.block.ForgeBlockData; -import com.dfsek.terra.forge.world.block.ForgeBlockType; -import com.dfsek.terra.forge.world.block.data.ForgeDirectional; -import com.dfsek.terra.forge.world.block.data.ForgeMultipleFacing; -import com.dfsek.terra.forge.world.block.data.ForgeOrientable; -import com.dfsek.terra.forge.world.block.data.ForgeRotatable; -import com.dfsek.terra.forge.world.block.data.ForgeSlab; -import com.dfsek.terra.forge.world.block.data.ForgeStairs; -import com.dfsek.terra.forge.world.block.data.ForgeWaterlogged; -import com.dfsek.terra.forge.world.entity.ForgeCommandSender; -import com.dfsek.terra.forge.world.entity.ForgeEntityType; -import com.dfsek.terra.forge.world.entity.ForgePlayer; -import com.dfsek.terra.forge.world.handles.world.ForgeWorldHandle; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.command.CommandSource; -import net.minecraft.command.ICommandSource; -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.state.properties.BlockStateProperties; -import net.minecraft.util.Direction; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IWorld; - -import java.util.Arrays; - -public final class ForgeAdapter { - public static BlockPos adapt(Vector3 v) { - return new BlockPos(v.getBlockX(), v.getBlockY(), v.getBlockZ()); - } - - public static Vector3 adapt(BlockPos pos) { - return new Vector3(pos.getX(), pos.getY(), pos.getZ()); - } - - public static ForgeBlockData adapt(BlockState state) { - if(state.hasProperty(BlockStateProperties.STAIRS_SHAPE)) return new ForgeStairs(state); - - if(state.hasProperty(BlockStateProperties.SLAB_TYPE)) return new ForgeSlab(state); - - if(state.hasProperty(BlockStateProperties.AXIS)) return new ForgeOrientable(state, BlockStateProperties.AXIS); - if(state.hasProperty(BlockStateProperties.HORIZONTAL_AXIS)) return new ForgeOrientable(state, BlockStateProperties.HORIZONTAL_AXIS); - - if(state.hasProperty(BlockStateProperties.ROTATION_16)) return new ForgeRotatable(state); - - if(state.hasProperty(BlockStateProperties.FACING)) return new ForgeDirectional(state, BlockStateProperties.FACING); - if(state.hasProperty(BlockStateProperties.FACING_HOPPER)) return new ForgeDirectional(state, BlockStateProperties.FACING_HOPPER); - if(state.hasProperty(BlockStateProperties.HORIZONTAL_FACING)) return new ForgeDirectional(state, BlockStateProperties.HORIZONTAL_FACING); - - if(state.getProperties().containsAll(Arrays.asList(BlockStateProperties.NORTH, BlockStateProperties.SOUTH, BlockStateProperties.EAST, BlockStateProperties.WEST))) - return new ForgeMultipleFacing(state); - if(state.hasProperty(BlockStateProperties.WATERLOGGED)) return new ForgeWaterlogged(state); - return new ForgeBlockData(state); - } - - public static CommandSender adapt(CommandSource serverCommandSource) { - if(serverCommandSource.getEntity() instanceof PlayerEntity) return new ForgePlayer((PlayerEntity) serverCommandSource.getEntity()); - return new ForgeCommandSender(serverCommandSource); - } - - public static Direction adapt(BlockFace face) { - switch(face) { - case NORTH: - return Direction.NORTH; - case WEST: - return Direction.WEST; - case SOUTH: - return Direction.SOUTH; - case EAST: - return Direction.EAST; - case UP: - return Direction.UP; - case DOWN: - return Direction.DOWN; - default: - throw new IllegalArgumentException("Illegal direction: " + face); - } - } - - public static BlockType adapt(Block block) { - return new ForgeBlockType(block); - } - - public static EntityType adapt(net.minecraft.entity.EntityType entityType) { - return new ForgeEntityType(entityType); - } - - public static net.minecraft.entity.EntityType adapt(EntityType entityType) { - return ((ForgeEntityType) entityType).getHandle(); - } - - public static ItemStack adapt(com.dfsek.terra.api.platform.inventory.ItemStack itemStack) { - return ((ForgeItemStack) itemStack).getHandle(); - } - - public static com.dfsek.terra.api.platform.inventory.ItemStack adapt(ItemStack itemStack) { - return new ForgeItemStack(itemStack); - } - - public static com.dfsek.terra.api.platform.inventory.Item adapt(Item item) { - return new ForgeItem(item); - } - - public static Enchantment adapt(net.minecraft.enchantment.Enchantment enchantment) { - return new ForgeEnchantment(enchantment); - } - - public static net.minecraft.enchantment.Enchantment adapt(Enchantment enchantment) { - return ((ForgeEnchantment) enchantment).getHandle(); - } - - public IWorld adapt(ForgeWorldHandle worldHandle) { - return worldHandle.getWorld(); - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/ForgeBiome.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/ForgeBiome.java deleted file mode 100644 index cfddb6e88..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/ForgeBiome.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.dfsek.terra.forge.world; - -import com.dfsek.terra.api.platform.world.Biome; - -public class ForgeBiome implements Biome { - private final net.minecraft.world.biome.Biome delegate; - - public ForgeBiome(net.minecraft.world.biome.Biome delegate) { - this.delegate = delegate; - } - - - @Override - public net.minecraft.world.biome.Biome getHandle() { - return delegate; - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/ForgeTree.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/ForgeTree.java deleted file mode 100644 index c94b85a29..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/ForgeTree.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.dfsek.terra.forge.world; - -import com.dfsek.terra.api.TerraPlugin; -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 com.dfsek.terra.forge.world.generator.ForgeChunkGenerator; -import com.dfsek.terra.forge.world.handles.world.ForgeWorldAccess; -import com.dfsek.terra.profiler.ProfileFrame; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.ISeedReader; -import net.minecraft.world.gen.ChunkGenerator; -import net.minecraft.world.gen.feature.ConfiguredFeature; - -import java.util.Locale; -import java.util.Random; - -public class ForgeTree implements Tree { - private final ConfiguredFeature delegate; - private final String id; - private final TerraPlugin main; - - public ForgeTree(ConfiguredFeature delegate, String id, TerraPlugin main) { - this.delegate = delegate; - this.id = id; - this.main = main; - } - - @Override - public boolean plant(Location l, Random r) { - try(ProfileFrame ignore = main.getProfiler().profile("fabric_tree:" + id.toLowerCase(Locale.ROOT))) { - ForgeWorldAccess fabricWorldAccess = ((ForgeWorldAccess) l.getWorld()); - ChunkGenerator generatorWrapper = ((ForgeChunkGenerator) fabricWorldAccess.getGenerator()).getHandle(); - return delegate.place((ISeedReader) fabricWorldAccess.getHandle(), generatorWrapper, r, new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ())); - } - } - - @Override - public MaterialSet getSpawnable() { - return MaterialSet.get(main.getWorldHandle().createBlockData("minecraft:grass_block"), - main.getWorldHandle().createBlockData("minecraft:podzol"), - main.getWorldHandle().createBlockData("minecraft:mycelium")); - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/ForgeBlockType.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/ForgeBlockType.java deleted file mode 100644 index 05c87167a..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/ForgeBlockType.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.dfsek.terra.forge.world.block; - -import com.dfsek.terra.api.platform.block.BlockData; -import com.dfsek.terra.api.platform.block.BlockType; -import com.dfsek.terra.forge.world.ForgeAdapter; -import net.minecraft.block.Block; -import net.minecraft.block.Blocks; - -public class ForgeBlockType implements BlockType { - private final Block delegate; - - public ForgeBlockType(Block delegate) { - this.delegate = delegate; - } - - @Override - public Block getHandle() { - return delegate; - } - - @Override - public BlockData getDefaultData() { - return ForgeAdapter.adapt(delegate.defaultBlockState()); - } - - @Override - public boolean isSolid() { - return delegate.defaultBlockState().canOcclude(); - } - - @Override - public boolean isWater() { - return delegate == Blocks.WATER; - } - - @Override - public int hashCode() { - return delegate.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if(!(obj instanceof ForgeBlockType)) return false; - return ((ForgeBlockType) obj).delegate == delegate; - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/state/ForgeBlockState.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/state/ForgeBlockState.java deleted file mode 100644 index 1ad7a6098..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/state/ForgeBlockState.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.dfsek.terra.forge.world.block.state; - -import com.dfsek.terra.api.platform.block.Block; -import com.dfsek.terra.api.platform.block.BlockData; -import com.dfsek.terra.api.platform.block.state.BlockState; -import com.dfsek.terra.forge.world.ForgeAdapter; -import com.dfsek.terra.forge.world.block.ForgeBlock; -import com.dfsek.terra.forge.world.handles.world.ForgeWorldHandle; -import net.minecraft.tileentity.LockableLootTileEntity; -import net.minecraft.tileentity.MobSpawnerTileEntity; -import net.minecraft.tileentity.SignTileEntity; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.IWorld; - -public class ForgeBlockState implements BlockState { - protected final TileEntity blockEntity; - private final IWorld worldAccess; - - public ForgeBlockState(TileEntity blockEntity, IWorld worldAccess) { - this.blockEntity = blockEntity; - this.worldAccess = worldAccess; - } - - public static ForgeBlockState newInstance(Block block) { - IWorld worldAccess = ((ForgeWorldHandle) block.getLocation().getWorld()).getWorld(); - - TileEntity entity = worldAccess.getBlockEntity(ForgeAdapter.adapt(block.getLocation().toVector())); - if(entity instanceof SignTileEntity) { - return new ForgeSign((SignTileEntity) entity, worldAccess); - } else if(entity instanceof MobSpawnerTileEntity) { - return new ForgeMobSpawner((MobSpawnerTileEntity) entity, worldAccess); - } else if(entity instanceof LockableLootTileEntity) { - return new ForgeContainer((LockableLootTileEntity) entity, worldAccess); - } - return null; - } - - @Override - public TileEntity getHandle() { - return blockEntity; - } - - @Override - public Block getBlock() { - return new ForgeBlock(blockEntity.getBlockPos(), blockEntity.getLevel()); - } - - @Override - public int getX() { - return blockEntity.getBlockPos().getX(); - } - - @Override - public int getY() { - return blockEntity.getBlockPos().getY(); - } - - @Override - public int getZ() { - return blockEntity.getBlockPos().getZ(); - } - - @Override - public BlockData getBlockData() { - return ForgeAdapter.adapt(blockEntity.getBlockState()); - } - - @Override - public boolean update(boolean applyPhysics) { - worldAccess.getChunk(blockEntity.getBlockPos()).setBlockEntity(blockEntity.getBlockPos(), blockEntity); - return true; - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/state/ForgeContainer.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/state/ForgeContainer.java deleted file mode 100644 index c10c9ef03..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/state/ForgeContainer.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.dfsek.terra.forge.world.block.state; - -import com.dfsek.terra.api.platform.block.state.Container; -import com.dfsek.terra.api.platform.inventory.Inventory; -import com.dfsek.terra.forge.inventory.ForgeInventory; -import net.minecraft.tileentity.LockableLootTileEntity; -import net.minecraft.world.IWorld; - -public class ForgeContainer extends ForgeBlockState implements Container { - public ForgeContainer(LockableLootTileEntity blockEntity, IWorld worldAccess) { - super(blockEntity, worldAccess); - } - - @Override - public Inventory getInventory() { - return new ForgeInventory(((LockableLootTileEntity) blockEntity)); - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/state/ForgeMobSpawner.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/state/ForgeMobSpawner.java deleted file mode 100644 index 95ca3d941..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/state/ForgeMobSpawner.java +++ /dev/null @@ -1,134 +0,0 @@ -package com.dfsek.terra.forge.world.block.state; - -import com.dfsek.terra.api.platform.block.state.MobSpawner; -import com.dfsek.terra.api.platform.block.state.SerialState; -import com.dfsek.terra.api.platform.entity.EntityType; -import com.dfsek.terra.forge.TerraForgePlugin; -import com.dfsek.terra.forge.world.ForgeAdapter; -import net.minecraft.tileentity.MobSpawnerTileEntity; -import net.minecraft.util.registry.Registry; -import net.minecraft.world.IWorld; -import net.minecraftforge.registries.ForgeRegistries; -import org.jetbrains.annotations.NotNull; - -public class ForgeMobSpawner extends ForgeBlockState implements MobSpawner { // TODO: finish implementation / refactor API because bukkit doesnt expose most of the stuff spawners can do - - - public ForgeMobSpawner(MobSpawnerTileEntity blockEntity, IWorld worldAccess) { - super(blockEntity, worldAccess); - } - - @Override - public EntityType getSpawnedType() { - return ForgeAdapter.adapt(ForgeRegistries.ENTITIES.getValue(((MobSpawnerTileEntity) blockEntity).getSpawner().getSpawnerEntity().getType().getRegistryName())); - } - - @Override - public void setSpawnedType(@NotNull EntityType creatureType) { - ((MobSpawnerTileEntity) blockEntity).getSpawner().setEntityId(ForgeAdapter.adapt(creatureType)); - } - - @Override - public int getDelay() { - return 0; - } - - @Override - public void setDelay(int delay) { - - } - - @Override - public int getMinSpawnDelay() { - return 0; - } - - @Override - public void setMinSpawnDelay(int delay) { - - } - - @Override - public int getMaxSpawnDelay() { - return 0; - } - - @Override - public void setMaxSpawnDelay(int delay) { - - } - - @Override - public int getSpawnCount() { - return 0; - } - - @Override - public void setSpawnCount(int spawnCount) { - - } - - @Override - public int getMaxNearbyEntities() { - return 0; - } - - @Override - public void setMaxNearbyEntities(int maxNearbyEntities) { - - } - - @Override - public int getRequiredPlayerRange() { - return 0; - } - - @Override - public void setRequiredPlayerRange(int requiredPlayerRange) { - - } - - @Override - public int getSpawnRange() { - return 0; - } - - @Override - public void setSpawnRange(int spawnRange) { - - } - - @Override - public void applyState(String state) { - SerialState.parse(state).forEach((k, v) -> { - switch(k) { - case "type": - setSpawnedType(TerraForgePlugin.getInstance().getWorldHandle().getEntity(v)); - return; - case "delay": - setDelay(Integer.parseInt(v)); - return; - case "min_delay": - setMinSpawnDelay(Integer.parseInt(v)); - return; - case "max_delay": - setMaxSpawnDelay(Integer.parseInt(v)); - return; - case "spawn_count": - setSpawnCount(Integer.parseInt(v)); - return; - case "spawn_range": - setSpawnRange(Integer.parseInt(v)); - return; - case "max_nearby": - setMaxNearbyEntities(Integer.parseInt(v)); - return; - case "required_player_range": - setRequiredPlayerRange(Integer.parseInt(v)); - return; - default: - throw new IllegalArgumentException("Invalid property: " + k); - } - }); - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/state/ForgeSign.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/state/ForgeSign.java deleted file mode 100644 index 899fe900e..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/block/state/ForgeSign.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.dfsek.terra.forge.world.block.state; - -import com.dfsek.terra.api.platform.block.state.SerialState; -import com.dfsek.terra.api.platform.block.state.Sign; -import net.minecraft.tileentity.SignTileEntity; -import net.minecraft.util.text.StringTextComponent; -import net.minecraft.world.IWorld; -import org.jetbrains.annotations.NotNull; - -public class ForgeSign extends ForgeBlockState implements Sign { - public ForgeSign(SignTileEntity blockEntity, IWorld worldAccess) { - super(blockEntity, worldAccess); - } - - @Override - public @NotNull String[] getLines() { - SignTileEntity sign = (SignTileEntity) blockEntity; - - return new String[] { - sign.getMessage(0).getString(), - sign.getMessage(1).getString(), - sign.getMessage(2).getString(), - sign.getMessage(3).getString() - }; - } - - @Override - public @NotNull String getLine(int index) throws IndexOutOfBoundsException { - return ((SignTileEntity) blockEntity).getMessage(index).getString(); - } - - @Override - public void setLine(int index, @NotNull String line) throws IndexOutOfBoundsException { - ((SignTileEntity) blockEntity).setMessage(index, new StringTextComponent(line)); - } - - @Override - public void applyState(String state) { - SerialState.parse(state).forEach((k, v) -> { - if(!k.startsWith("text")) throw new IllegalArgumentException("Invalid property: " + k); - setLine(Integer.parseInt(k.substring(4)), v); - }); - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/entity/ForgeCommandSender.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/entity/ForgeCommandSender.java deleted file mode 100644 index 042efbae3..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/entity/ForgeCommandSender.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.dfsek.terra.forge.world.entity; - -import com.dfsek.terra.api.platform.CommandSender; -import net.minecraft.command.CommandSource; -import net.minecraft.util.text.StringTextComponent; - -public class ForgeCommandSender implements CommandSender { - private final CommandSource delegate; - - public ForgeCommandSender(CommandSource delegate) { - this.delegate = delegate; - } - - @Override - public void sendMessage(String message) { - delegate.sendSuccess(new StringTextComponent(message), true); - } - - @Override - public Object getHandle() { - return delegate; - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/entity/ForgeEntity.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/entity/ForgeEntity.java deleted file mode 100644 index df35af7fb..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/entity/ForgeEntity.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.dfsek.terra.forge.world.entity; - -import com.dfsek.terra.api.math.vector.Location; -import com.dfsek.terra.api.platform.entity.Entity; -import com.dfsek.terra.api.platform.world.World; -import com.dfsek.terra.forge.world.ForgeAdapter; -import com.dfsek.terra.forge.world.handles.world.ForgeWorldAccess; -import com.dfsek.terra.forge.world.handles.world.ForgeWorldHandle; -import net.minecraft.world.server.ServerWorld; - -public class ForgeEntity implements Entity { - private final net.minecraft.entity.Entity delegate; - - public ForgeEntity(net.minecraft.entity.Entity delegate) { - this.delegate = delegate; - } - - @Override - public void sendMessage(String message) { - - } - - @Override - public Object getHandle() { - return null; - } - - @Override - public Location getLocation() { - return new Location(new ForgeWorldAccess(delegate.level), ForgeAdapter.adapt(delegate.blockPosition())); - } - - @Override - public void setLocation(Location location) { - delegate.teleportTo(location.getX(), location.getY(), location.getZ()); - delegate.setLevel((ServerWorld) ((ForgeWorldHandle) location).getWorld()); - } - - @Override - public World getWorld() { - return new ForgeWorldAccess(delegate.level); - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/entity/ForgeEntityType.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/entity/ForgeEntityType.java deleted file mode 100644 index 42ad0e91d..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/entity/ForgeEntityType.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.dfsek.terra.forge.world.entity; - -import com.dfsek.terra.api.platform.entity.EntityType; - -public class ForgeEntityType implements EntityType { - private final net.minecraft.entity.EntityType type; - - public ForgeEntityType(net.minecraft.entity.EntityType type) { - this.type = type; - } - - @Override - public net.minecraft.entity.EntityType getHandle() { - return type; - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/entity/ForgePlayer.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/entity/ForgePlayer.java deleted file mode 100644 index 87ea1ebc1..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/entity/ForgePlayer.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.dfsek.terra.forge.world.entity; - -import com.dfsek.terra.api.math.vector.Location; -import com.dfsek.terra.api.platform.entity.Player; -import com.dfsek.terra.api.platform.world.World; -import com.dfsek.terra.forge.world.ForgeAdapter; -import com.dfsek.terra.forge.world.handles.world.ForgeWorldAccess; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.text.StringTextComponent; - -public class ForgePlayer implements Player { - private final PlayerEntity delegate; - - public ForgePlayer(PlayerEntity delegate) { - this.delegate = delegate; - } - - @Override - public void sendMessage(String message) { - delegate.displayClientMessage(new StringTextComponent(message), false); - } - - @Override - public Object getHandle() { - return delegate; - } - - @Override - public Location getLocation() { - return ForgeAdapter.adapt(delegate.blockPosition()).toLocation(new ForgeWorldAccess(delegate.level)); - } - - @Override - public World getWorld() { - return new ForgeWorldAccess(delegate.level); - } - - @Override - public void setLocation(Location location) { - delegate.teleportTo(location.getX(), location.getY(), location.getZ()); - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/generator/ForgeChunkData.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/generator/ForgeChunkData.java deleted file mode 100644 index 14415feed..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/generator/ForgeChunkData.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.dfsek.terra.forge.world.generator; - -import com.dfsek.terra.api.platform.block.BlockData; -import com.dfsek.terra.api.platform.world.generator.ChunkData; -import com.dfsek.terra.forge.world.block.ForgeBlockData; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.chunk.Chunk; -import net.minecraft.world.chunk.IChunk; -import org.jetbrains.annotations.NotNull; - -public class ForgeChunkData implements ChunkData { - private final IChunk handle; - - public ForgeChunkData(IChunk handle) { - this.handle = handle; - } - - @Override - public IChunk getHandle() { - return handle; - } - - @Override - public int getMaxHeight() { - return handle.getMaxBuildHeight(); - } - - @Override - public void setBlock(int x, int y, int z, @NotNull BlockData blockData) { - handle.setBlockState(new BlockPos(x, y, z), ((ForgeBlockData) blockData).getHandle(), false); - } - - @Override - public @NotNull BlockData getBlockData(int x, int y, int z) { - return new ForgeBlockData(handle.getBlockState(new BlockPos(x, y, z))); - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/generator/ForgeChunkGenerator.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/generator/ForgeChunkGenerator.java deleted file mode 100644 index dad4fe98b..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/generator/ForgeChunkGenerator.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.dfsek.terra.forge.world.generator; - -import com.dfsek.terra.api.platform.world.generator.ChunkGenerator; - -public class ForgeChunkGenerator implements ChunkGenerator { - private final net.minecraft.world.gen.ChunkGenerator delegate; - - public ForgeChunkGenerator(net.minecraft.world.gen.ChunkGenerator delegate) { - this.delegate = delegate; - } - - @Override - public net.minecraft.world.gen.ChunkGenerator getHandle() { - return delegate; - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/handles/ForgeWorld.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/handles/ForgeWorld.java deleted file mode 100644 index a4bfa54e2..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/handles/ForgeWorld.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.dfsek.terra.forge.world.handles; - -import com.dfsek.terra.api.math.vector.Location; -import com.dfsek.terra.api.platform.block.Block; -import com.dfsek.terra.api.platform.entity.Entity; -import com.dfsek.terra.api.platform.entity.EntityType; -import com.dfsek.terra.api.platform.world.Chunk; -import com.dfsek.terra.api.platform.world.World; -import com.dfsek.terra.api.platform.world.generator.ChunkGenerator; -import com.dfsek.terra.forge.world.ForgeAdapter; -import com.dfsek.terra.forge.world.block.ForgeBlock; -import com.dfsek.terra.forge.world.entity.ForgeEntity; -import com.dfsek.terra.forge.world.handles.chunk.ForgeChunk; -import com.dfsek.terra.forge.world.handles.world.ForgeWorldHandle; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IServerWorld; -import net.minecraft.world.server.ServerWorld; - -public class ForgeWorld implements World, ForgeWorldHandle { - - private final Handle delegate; - - public ForgeWorld(ServerWorld world, ChunkGenerator generator) { - this.delegate = new Handle(world, generator); - } - - @Override - public long getSeed() { - return delegate.world.getSeed(); - } - - @Override - public int getMaxHeight() { - return delegate.world.getHeight(); - } - - @Override - public ChunkGenerator getGenerator() { - return delegate.generator; - } - - @Override - public Chunk getChunkAt(int x, int z) { - return new ForgeChunk(delegate.world.getChunk(x, z)); - } - - @Override - public Block getBlockAt(int x, int y, int z) { - BlockPos pos = new BlockPos(x, y, z); - return new ForgeBlock(pos, delegate.world); - } - - @Override - public int hashCode() { - return ((IServerWorld) delegate.world).getLevel().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if(!(obj instanceof ForgeWorld)) return false; - return ((IServerWorld) ((ForgeWorld) obj).delegate.world).getLevel().equals(((IServerWorld) delegate.world).getLevel()); - } - - @Override - public Entity spawnEntity(Location location, EntityType entityType) { - net.minecraft.entity.Entity entity = ForgeAdapter.adapt(entityType).create(delegate.world); - entity.setPos(location.getX(), location.getY(), location.getZ()); - delegate.world.addFreshEntity(entity); - return new ForgeEntity(entity); - } - - @Override - public int getMinHeight() { - return 0; - } - - @Override - public Handle getHandle() { - return null; - } - - @Override - public ServerWorld getWorld() { - return delegate.getWorld(); - } - - public static final class Handle { - private final ServerWorld world; - private final ChunkGenerator generator; - - private Handle(ServerWorld world, ChunkGenerator generator) { - this.world = world; - this.generator = generator; - } - - public ChunkGenerator getGenerator() { - return generator; - } - - public ServerWorld getWorld() { - return world; - } - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/handles/chunk/ForgeChunk.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/handles/chunk/ForgeChunk.java deleted file mode 100644 index da28514f9..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/handles/chunk/ForgeChunk.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.dfsek.terra.forge.world.handles.chunk; - -import com.dfsek.terra.api.platform.block.Block; -import com.dfsek.terra.api.platform.block.BlockData; -import com.dfsek.terra.api.platform.world.Chunk; -import com.dfsek.terra.api.platform.world.World; -import com.dfsek.terra.forge.world.block.ForgeBlockData; -import net.minecraft.util.math.BlockPos; -import org.jetbrains.annotations.NotNull; - -public class ForgeChunk implements Chunk { - private final net.minecraft.world.chunk.Chunk chunk; - - public ForgeChunk(net.minecraft.world.chunk.Chunk chunk) { - this.chunk = chunk; - } - - @Override - public int getX() { - return chunk.getPos().x; - } - - @Override - public int getZ() { - return chunk.getPos().z; - } - - @Override - public World getWorld() { - return null; - } - - @Override - public Block getBlock(int x, int y, int z) { - return null; - } - - @Override - public net.minecraft.world.chunk.Chunk getHandle() { - return chunk; - } - - @Override - public void setBlock(int x, int y, int z, @NotNull BlockData blockData) { - chunk.setBlockState(new BlockPos(x, y, z), ((ForgeBlockData) blockData).getHandle(), false); - } - - @Override - public @NotNull BlockData getBlockData(int x, int y, int z) { - return getBlock(x, y, z).getBlockData(); - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/handles/chunk/ForgeChunkWorldAccess.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/handles/chunk/ForgeChunkWorldAccess.java deleted file mode 100644 index a405910c4..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/handles/chunk/ForgeChunkWorldAccess.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.dfsek.terra.forge.world.handles.chunk; - -import com.dfsek.terra.api.platform.block.Block; -import com.dfsek.terra.api.platform.block.BlockData; -import com.dfsek.terra.api.platform.world.Chunk; -import com.dfsek.terra.api.platform.world.World; -import com.dfsek.terra.forge.world.block.ForgeBlock; -import com.dfsek.terra.forge.world.block.ForgeBlockData; -import com.dfsek.terra.forge.world.handles.world.ForgeWorldAccess; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IWorld; -import org.jetbrains.annotations.NotNull; - -public class ForgeChunkWorldAccess implements Chunk { - private final IWorld chunkRegion; - private final int x; - private final int z; - - public ForgeChunkWorldAccess(IWorld chunkRegion, int x, int z) { - this.chunkRegion = chunkRegion; - this.x = x << 4; - this.z = z << 4; - } - - @Override - public int getX() { - return x >> 4; - } - - @Override - public int getZ() { - return z >> 4; - } - - @Override - public World getWorld() { - return new ForgeWorldAccess(chunkRegion); - } - - @Override - public Block getBlock(int x, int y, int z) { - BlockPos pos = new BlockPos(x + this.x, y, z + this.z); - return new ForgeBlock(pos, chunkRegion); - } - - @Override - public IWorld getHandle() { - return chunkRegion; - } - - @Override - public void setBlock(int x, int y, int z, @NotNull BlockData blockData) { - chunkRegion.setBlock(new BlockPos(x + this.x, y, z + this.z), ((ForgeBlockData) blockData).getHandle(), 0); - } - - @Override - public @NotNull BlockData getBlockData(int x, int y, int z) { - return getBlock(x, y, z).getBlockData(); - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/handles/world/ForgeSeededWorldAccess.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/handles/world/ForgeSeededWorldAccess.java deleted file mode 100644 index bbc5aa411..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/handles/world/ForgeSeededWorldAccess.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.dfsek.terra.forge.world.handles.world; - -import com.dfsek.terra.api.math.vector.Location; -import com.dfsek.terra.api.platform.block.Block; -import com.dfsek.terra.api.platform.entity.Entity; -import com.dfsek.terra.api.platform.entity.EntityType; -import com.dfsek.terra.api.platform.world.Chunk; -import com.dfsek.terra.api.platform.world.World; -import com.dfsek.terra.api.platform.world.generator.ChunkGenerator; -import com.dfsek.terra.forge.world.ForgeAdapter; -import com.dfsek.terra.forge.world.block.ForgeBlock; -import com.dfsek.terra.forge.world.entity.ForgeEntity; -import com.dfsek.terra.forge.world.generator.ForgeChunkGenerator; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IServerWorld; -import net.minecraft.world.IWorld; -import net.minecraft.world.server.ServerWorld; - -public class ForgeSeededWorldAccess implements World, ForgeWorldHandle { - - private final Handle handle; - - public ForgeSeededWorldAccess(IWorld access, long seed, net.minecraft.world.gen.ChunkGenerator generator) { - this.handle = new Handle(access, seed, generator); - } - - @Override - public long getSeed() { - return handle.getSeed(); - } - - @Override - public int getMaxHeight() { - return handle.getWorldAccess().getMaxBuildHeight(); - } - - @Override - public ChunkGenerator getGenerator() { - return new ForgeChunkGenerator(handle.getGenerator()); - } - - @Override - public Chunk getChunkAt(int x, int z) { - return null; - } - - @Override - public Block getBlockAt(int x, int y, int z) { - BlockPos pos = new BlockPos(x, y, z); - return new ForgeBlock(pos, handle.worldAccess); - } - - @Override - public Entity spawnEntity(Location location, EntityType entityType) { - net.minecraft.entity.Entity entity = ForgeAdapter.adapt(entityType).create((ServerWorld) handle.worldAccess); - entity.setPos(location.getX(), location.getY(), location.getZ()); - handle.worldAccess.addFreshEntity(entity); - return new ForgeEntity(entity); - } - - @Override - public int getMinHeight() { - return 0; - } - - @Override - public int hashCode() { - return ((IServerWorld) handle.worldAccess).getLevel().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if(!(obj instanceof ForgeSeededWorldAccess)) return false; - return ((IServerWorld) ((ForgeSeededWorldAccess) obj).handle.worldAccess).getLevel().equals(((IServerWorld) handle.worldAccess).getLevel()); - } - - @Override - public Handle getHandle() { - return handle; - } - - @Override - public IWorld getWorld() { - return handle.worldAccess; - } - - public static class Handle { - private final IWorld worldAccess; - private final long seed; - private final net.minecraft.world.gen.ChunkGenerator generator; - - public Handle(IWorld worldAccess, long seed, net.minecraft.world.gen.ChunkGenerator generator) { - this.worldAccess = worldAccess; - this.seed = seed; - this.generator = generator; - } - - public net.minecraft.world.gen.ChunkGenerator getGenerator() { - return generator; - } - - public long getSeed() { - return seed; - } - - public IWorld getWorldAccess() { - return worldAccess; - } - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/handles/world/ForgeWorldAccess.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/handles/world/ForgeWorldAccess.java deleted file mode 100644 index 8a061d49b..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/handles/world/ForgeWorldAccess.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.dfsek.terra.forge.world.handles.world; - -import com.dfsek.terra.api.math.vector.Location; -import com.dfsek.terra.api.platform.block.Block; -import com.dfsek.terra.api.platform.entity.Entity; -import com.dfsek.terra.api.platform.entity.EntityType; -import com.dfsek.terra.api.platform.world.Chunk; -import com.dfsek.terra.api.platform.world.World; -import com.dfsek.terra.api.platform.world.generator.ChunkGenerator; -import com.dfsek.terra.forge.world.ForgeAdapter; -import com.dfsek.terra.forge.world.block.ForgeBlock; -import com.dfsek.terra.forge.world.entity.ForgeEntity; -import com.dfsek.terra.forge.world.generator.ForgeChunkGenerator; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.ISeedReader; -import net.minecraft.world.IServerWorld; -import net.minecraft.world.IWorld; - -public class ForgeWorldAccess implements World, ForgeWorldHandle { - private final IWorld delegate; - - public ForgeWorldAccess(IWorld delegate) { - this.delegate = delegate; - } - - @Override - public long getSeed() { - return ((ISeedReader) delegate).getSeed(); - } - - @Override - public int getMaxHeight() { - return delegate.getHeight(); - } - - @Override - public ChunkGenerator getGenerator() { - return new ForgeChunkGenerator(((IServerWorld) delegate).getLevel().getChunkSource().getGenerator()); - } - - @Override - public Chunk getChunkAt(int x, int z) { - return null; - } - - @Override - public Block getBlockAt(int x, int y, int z) { - BlockPos pos = new BlockPos(x, y, z); - return new ForgeBlock(pos, delegate); - } - - @Override - public Entity spawnEntity(Location location, EntityType entityType) { - net.minecraft.entity.Entity entity = ForgeAdapter.adapt(entityType).create(((IServerWorld) delegate).getLevel()); - entity.setPos(location.getX(), location.getY(), location.getZ()); - delegate.addFreshEntity(entity); - return new ForgeEntity(entity); - } - - @Override - public int getMinHeight() { - return 0; - } - - @Override - public IWorld getHandle() { - return delegate; - } - - @Override - public IWorld getWorld() { - return delegate; - } - - @Override - public int hashCode() { - return ((IServerWorld) delegate).getLevel().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if(!(obj instanceof ForgeWorldAccess)) return false; - return ((IServerWorld) ((ForgeWorldAccess) obj).delegate).getLevel().equals(((IServerWorld) delegate).getLevel()); - } -} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/handles/world/ForgeWorldHandle.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/world/handles/world/ForgeWorldHandle.java deleted file mode 100644 index a0790e276..000000000 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/world/handles/world/ForgeWorldHandle.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.dfsek.terra.forge.world.handles.world; - -import net.minecraft.world.IWorld; - -public interface ForgeWorldHandle { - IWorld getWorld(); -} diff --git a/platforms/forge/src/main/resources/terra.mixins.json b/platforms/forge/src/main/resources/terra.mixins.json index c18783888..3b7f9a0c5 100644 --- a/platforms/forge/src/main/resources/terra.mixins.json +++ b/platforms/forge/src/main/resources/terra.mixins.json @@ -4,6 +4,31 @@ "compatibilityLevel": "JAVA_8", "refmap": "terra-refmap.json", "mixins": [ + "DimensionGeneratorSettingsMixin", + "access.AbstractSpawnerAccessor", + "implementations.BiomeMixin", + "implementations.ChunkGeneratorMixin", + "implementations.ConfiguredFeatureMixin", + "implementations.block.BlockMixin", + "implementations.block.TileEntityMixin", + "implementations.block.state.LockableLootTileEntityMixin", + "implementations.block.state.MobSpawnerTileEntityMixin", + "implementations.block.state.SignTileEntityMixin", + "implementations.chunk.ChunkMixin", + "implementations.chunk.WorldGenRegionMixin", + "implementations.chunk.data.ChunkPrimerMixin", + "implementations.entity.CommandSourceMixin", + "implementations.entity.EntityMixin", + "implementations.entity.EntityTypeMixin", + "implementations.entity.PlayerEntityMixin", + "implementations.inventory.LockableTileEntityMixin", + "implementations.inventory.item.ItemMixin", + "implementations.inventory.item.ItemStackMixin", + "implementations.inventory.meta.EnchantmentMixin", + "implementations.inventory.meta.ItemStackDamageableMixin", + "implementations.inventory.meta.ItemStackMetaMixin", + "implementations.world.ServerWorldMixin", + "implementations.world.WorldGenRegionMixin" ], "client": [ ],