fabric stuff

This commit is contained in:
dfsek
2021-02-22 20:47:06 -07:00
parent 358bd350b5
commit 268cc7c48b
10 changed files with 199 additions and 78 deletions
@@ -3,19 +3,27 @@ package com.dfsek.terra.fabric;
import com.dfsek.tectonic.loading.TypeRegistry; import com.dfsek.tectonic.loading.TypeRegistry;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.addons.TerraAddon; import com.dfsek.terra.api.addons.TerraAddon;
import com.dfsek.terra.api.addons.annotations.Addon;
import com.dfsek.terra.api.addons.annotations.Author;
import com.dfsek.terra.api.addons.annotations.Version;
import com.dfsek.terra.api.event.EventListener;
import com.dfsek.terra.api.event.EventManager; import com.dfsek.terra.api.event.EventManager;
import com.dfsek.terra.api.event.TerraEventManager; 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.block.BlockData; import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.handle.ItemHandle; import com.dfsek.terra.api.platform.handle.ItemHandle;
import com.dfsek.terra.api.platform.handle.WorldHandle; import com.dfsek.terra.api.platform.handle.WorldHandle;
import com.dfsek.terra.api.platform.world.World; import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.api.registry.CheckedRegistry; import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.registry.LockedRegistry; import com.dfsek.terra.api.registry.LockedRegistry;
import com.dfsek.terra.api.transform.MapTransform;
import com.dfsek.terra.api.transform.NotNullValidator; import com.dfsek.terra.api.transform.NotNullValidator;
import com.dfsek.terra.api.transform.Transformer; import com.dfsek.terra.api.transform.Transformer;
import com.dfsek.terra.api.util.DebugLogger; import com.dfsek.terra.api.util.DebugLogger;
import com.dfsek.terra.api.util.collections.MaterialSet;
import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.tree.Tree;
import com.dfsek.terra.config.GenericLoaders; import com.dfsek.terra.config.GenericLoaders;
import com.dfsek.terra.config.PluginConfig; import com.dfsek.terra.config.PluginConfig;
import com.dfsek.terra.config.lang.LangUtil; import com.dfsek.terra.config.lang.LangUtil;
@@ -23,11 +31,14 @@ import com.dfsek.terra.config.lang.Language;
import com.dfsek.terra.config.pack.ConfigPack; import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.fabric.inventory.FabricItemHandle; import com.dfsek.terra.fabric.inventory.FabricItemHandle;
import com.dfsek.terra.fabric.mixin.GeneratorTypeAccessor; import com.dfsek.terra.fabric.mixin.GeneratorTypeAccessor;
import com.dfsek.terra.fabric.world.FabricAdapter;
import com.dfsek.terra.fabric.world.FabricBiome; import com.dfsek.terra.fabric.world.FabricBiome;
import com.dfsek.terra.fabric.world.FabricTree;
import com.dfsek.terra.fabric.world.FabricWorldHandle; import com.dfsek.terra.fabric.world.FabricWorldHandle;
import com.dfsek.terra.fabric.world.TerraBiomeSource; import com.dfsek.terra.fabric.world.TerraBiomeSource;
import com.dfsek.terra.fabric.world.features.PopulatorFeature; import com.dfsek.terra.fabric.world.features.PopulatorFeature;
import com.dfsek.terra.fabric.world.generator.FabricChunkGeneratorWrapper; import com.dfsek.terra.fabric.world.generator.FabricChunkGeneratorWrapper;
import com.dfsek.terra.registry.exception.DuplicateEntryException;
import com.dfsek.terra.registry.master.AddonRegistry; import com.dfsek.terra.registry.master.AddonRegistry;
import com.dfsek.terra.registry.master.ConfigRegistry; import com.dfsek.terra.registry.master.ConfigRegistry;
import com.dfsek.terra.world.TerraWorld; import com.dfsek.terra.world.TerraWorld;
@@ -61,7 +72,6 @@ import org.apache.commons.io.FileUtils;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -90,33 +100,12 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
private final ConfigRegistry registry = new ConfigRegistry(); private final ConfigRegistry registry = new ConfigRegistry();
private final CheckedRegistry<ConfigPack> checkedRegistry = new CheckedRegistry<>(registry); private final CheckedRegistry<ConfigPack> checkedRegistry = new CheckedRegistry<>(registry);
private final AddonRegistry addonRegistry = new AddonRegistry(this); private final AddonRegistry addonRegistry = new AddonRegistry(new FabricAddon(this), this);
private final LockedRegistry<TerraAddon> addonLockedRegistry = new LockedRegistry<>(addonRegistry); private final LockedRegistry<TerraAddon> addonLockedRegistry = new LockedRegistry<>(addonRegistry);
private File config; private File config;
private static final Transformer<String, ConfiguredFeature<?, ?>> TREE_TRANSFORMER = new Transformer.Builder<String, ConfiguredFeature<?, ?>>()
.addTransform(TerraFabricPlugin::getFeature)
.addTransform(new MapTransform<String, ConfiguredFeature<?, ?>>()
.add("BROWN_MUSHROOM", ConfiguredFeatures.BROWN_MUSHROOM_GIANT)
.add("RED_MUSHROOM", ConfiguredFeatures.RED_MUSHROOM_GIANT)
.add("JUNGLE", ConfiguredFeatures.MEGA_JUNGLE_TREE)
.add("JUNGLE_COCOA", ConfiguredFeatures.JUNGLE_TREE)
.add("LARGE_OAK", ConfiguredFeatures.FANCY_OAK)
.add("LARGE_SPRUCE", ConfiguredFeatures.PINE)
.add("SMALL_JUNGLE", ConfiguredFeatures.JUNGLE_TREE)
.add("SWAMP_OAK", ConfiguredFeatures.SWAMP_TREE)
.add("TALL_BIRCH", ConfiguredFeatures.BIRCH_TALL)
.add("ACACIA", ConfiguredFeatures.ACACIA)
.add("BIRCH", ConfiguredFeatures.BIRCH)
.add("DARK_OAK", ConfiguredFeatures.DARK_OAK)
.add("OAK", ConfiguredFeatures.OAK)
.add("CHORUS_PLANT", ConfiguredFeatures.CHORUS_PLANT)
.add("SPRUCE", ConfiguredFeatures.SPRUCE)
.add("JUNGLE_BUSH", ConfiguredFeatures.JUNGLE_BUSH)
.add("MEGA_SPRUCE", ConfiguredFeatures.MEGA_SPRUCE)
.add("CRIMSON_FUNGUS", ConfiguredFeatures.CRIMSON_FUNGI)
.add("WARPED_FUNGUS", ConfiguredFeatures.WARPED_FUNGI)).build();
private final PluginConfig plugin = new PluginConfig(); private final PluginConfig plugin = new PluginConfig();
@Override @Override
@@ -259,20 +248,15 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
.build(); .build();
} }
private static ConfiguredFeature<?, ?> getFeature(String name) {
Class<ConfiguredFeatures> featuresClass = ConfiguredFeatures.class;
Field feature;
try {
feature = featuresClass.getField(name);
return (ConfiguredFeature<?, ?>) feature.get(null);
} catch(NoSuchFieldException | IllegalAccessException e) {
throw new IllegalArgumentException("No such feature: " + name);
}
}
@Override @Override
public void onInitialize() { public void onInitialize() {
logger.setLevel(Level.INFO); logger.setLevel(Level.INFO);
MaterialSet set = MaterialSet.get(FabricAdapter.adapt(Blocks.GRASS_BLOCK), FabricAdapter.adapt(Blocks.STONE));
logger.info("thing: " + set.contains(FabricAdapter.adapt(Blocks.STONE)));
logger.info("thing2: " + set.contains(FabricAdapter.adapt(Blocks.OAK_BUTTON)));
logger.info("thing3: " + Blocks.ACACIA_FENCE.getDefaultState().toString());
logger.info("thing4: " + Blocks.ACACIA_FENCE.toString());
instance = this; instance = this;
config = new File(FabricLoader.getInstance().getConfigDir().toFile(), "Terra"); config = new File(FabricLoader.getInstance().getConfigDir().toFile(), "Terra");
@@ -281,6 +265,10 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
LangUtil.load("en_us", this); LangUtil.load("en_us", this);
logger.info("Initializing Terra..."); logger.info("Initializing Terra...");
if(!addonRegistry.loadAll()) {
throw new IllegalStateException("Failed to load addons. Please correct addon installations to continue.");
}
registry.loadAll(this); registry.loadAll(this);
Registry.register(Registry.FEATURE, new Identifier("terra", "flora_populator"), POPULATOR_FEATURE); Registry.register(Registry.FEATURE, new Identifier("terra", "flora_populator"), POPULATOR_FEATURE);
@@ -307,4 +295,54 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
public EventManager getEventManager() { public EventManager getEventManager() {
return eventManager; return eventManager;
} }
@Addon("Terra-Fabric")
@Author("Terra")
@Version("1.0.0")
private static final class FabricAddon extends TerraAddon implements EventListener {
private final TerraPlugin main;
private FabricAddon(TerraPlugin main) {
this.main = main;
}
@Override
public void initialize() {
main.getEventManager().registerListener(this, this);
}
@Priority(Priority.LOWEST)
@Global
public void injectTrees(ConfigPackPreLoadEvent event) {
CheckedRegistry<Tree> treeRegistry = event.getPack().getTreeRegistry();
injectTree(treeRegistry, "BROWN_MUSHROOM", ConfiguredFeatures.BROWN_MUSHROOM_GIANT);
injectTree(treeRegistry, "RED_MUSHROOM", ConfiguredFeatures.RED_MUSHROOM_GIANT);
injectTree(treeRegistry, "JUNGLE", ConfiguredFeatures.MEGA_JUNGLE_TREE);
injectTree(treeRegistry, "JUNGLE_COCOA", ConfiguredFeatures.JUNGLE_TREE);
injectTree(treeRegistry, "LARGE_OAK", ConfiguredFeatures.FANCY_OAK);
injectTree(treeRegistry, "LARGE_SPRUCE", ConfiguredFeatures.PINE);
injectTree(treeRegistry, "SMALL_JUNGLE", ConfiguredFeatures.JUNGLE_TREE);
injectTree(treeRegistry, "SWAMP_OAK", ConfiguredFeatures.SWAMP_TREE);
injectTree(treeRegistry, "TALL_BIRCH", ConfiguredFeatures.BIRCH_TALL);
injectTree(treeRegistry, "ACACIA", ConfiguredFeatures.ACACIA);
injectTree(treeRegistry, "BIRCH", ConfiguredFeatures.BIRCH);
injectTree(treeRegistry, "DARK_OAK", ConfiguredFeatures.DARK_OAK);
injectTree(treeRegistry, "OAK", ConfiguredFeatures.OAK);
injectTree(treeRegistry, "CHORUS_PLANT", ConfiguredFeatures.CHORUS_PLANT);
injectTree(treeRegistry, "SPRUCE", ConfiguredFeatures.SPRUCE);
injectTree(treeRegistry, "JUNGLE_BUSH", ConfiguredFeatures.JUNGLE_BUSH);
injectTree(treeRegistry, "MEGA_SPRUCE", ConfiguredFeatures.MEGA_SPRUCE);
injectTree(treeRegistry, "CRIMSON_FUNGUS", ConfiguredFeatures.CRIMSON_FUNGI);
injectTree(treeRegistry, "WARPED_FUNGUS", ConfiguredFeatures.WARPED_FUNGI);
}
private void injectTree(CheckedRegistry<Tree> registry, String id, ConfiguredFeature<?, ?> tree) {
try {
registry.add(id, new FabricTree(tree));
} catch(DuplicateEntryException ignore) {
}
}
}
} }
@@ -0,0 +1,17 @@
package com.dfsek.terra.fabric.mixin;
import net.minecraft.state.State;
import net.minecraft.state.property.Property;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.Map;
import java.util.function.Function;
@Mixin(State.class)
public interface StateAccessor {
@Accessor
static Function<Map.Entry<Property<?>, Comparable<?>>, String> getPROPERTY_MAP_PRINTER() {
throw new UnsupportedOperationException();
}
}
@@ -0,0 +1,45 @@
package com.dfsek.terra.fabric.world;
import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.platform.block.BlockType;
import com.dfsek.terra.fabric.world.block.FabricBlockData;
import com.dfsek.terra.fabric.world.block.FabricBlockType;
import com.dfsek.terra.fabric.world.block.data.FabricMultipleFacing;
import com.dfsek.terra.fabric.world.block.data.FabricOrientable;
import com.dfsek.terra.fabric.world.block.data.FabricSlab;
import com.dfsek.terra.fabric.world.block.data.FabricStairs;
import com.dfsek.terra.fabric.world.block.data.FabricWaterlogged;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.BlockPos;
import java.util.Arrays;
public final class FabricAdapter {
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 FabricBlockData adapt(BlockState state) {
if(state.contains(Properties.STAIR_SHAPE)) return new FabricStairs(state);
if(state.contains(Properties.SLAB_TYPE)) return new FabricSlab(state);
if(state.contains(Properties.AXIS)) return new FabricOrientable(state);
if(state.getProperties().containsAll(Arrays.asList(Properties.NORTH, Properties.SOUTH, Properties.EAST, Properties.WEST)))
return new FabricMultipleFacing(state);
if(state.contains(Properties.WATERLOGGED)) return new FabricWaterlogged(state);
return new FabricBlockData(state);
}
public static BlockType adapt(Block block) {
return new FabricBlockType(block);
}
}
@@ -1,14 +0,0 @@
package com.dfsek.terra.fabric.world;
import com.dfsek.terra.api.math.vector.Vector3;
import net.minecraft.util.math.BlockPos;
public final class FabricAdapters {
public static BlockPos fromVector(Vector3 v) {
return new BlockPos(v.getBlockX(), v.getBlockY(), v.getBlockZ());
}
public static Vector3 toVector(BlockPos pos) {
return new Vector3(pos.getX(), pos.getY(), pos.getZ());
}
}
@@ -5,18 +5,10 @@ import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.entity.EntityType; import com.dfsek.terra.api.platform.entity.EntityType;
import com.dfsek.terra.api.platform.handle.WorldHandle; import com.dfsek.terra.api.platform.handle.WorldHandle;
import com.dfsek.terra.fabric.world.block.FabricBlockData; import com.dfsek.terra.fabric.world.block.FabricBlockData;
import com.dfsek.terra.fabric.world.block.data.FabricMultipleFacing;
import com.dfsek.terra.fabric.world.block.data.FabricOrientable;
import com.dfsek.terra.fabric.world.block.data.FabricSlab;
import com.dfsek.terra.fabric.world.block.data.FabricStairs;
import com.dfsek.terra.fabric.world.block.data.FabricWaterlogged;
import com.mojang.brigadier.StringReader; import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.command.argument.BlockArgumentParser; import net.minecraft.command.argument.BlockArgumentParser;
import net.minecraft.state.property.Properties;
import java.util.Arrays;
public class FabricWorldHandle implements WorldHandle { public class FabricWorldHandle implements WorldHandle {
@Override @Override
@@ -35,17 +27,7 @@ public class FabricWorldHandle implements WorldHandle {
try { try {
BlockState state = parser.parse(true).getBlockState(); BlockState state = parser.parse(true).getBlockState();
if(state == null) throw new IllegalArgumentException("Invalid data: " + data); if(state == null) throw new IllegalArgumentException("Invalid data: " + data);
return FabricAdapter.adapt(state);
if(state.contains(Properties.STAIR_SHAPE)) return new FabricStairs(state);
if(state.contains(Properties.SLAB_TYPE)) return new FabricSlab(state);
if(state.contains(Properties.AXIS)) return new FabricOrientable(state);
if(state.getProperties().containsAll(Arrays.asList(Properties.NORTH, Properties.SOUTH, Properties.EAST, Properties.WEST)))
return new FabricMultipleFacing(state);
if(state.contains(Properties.WATERLOGGED)) return new FabricWaterlogged(state);
return new FabricBlockData(state);
} catch(CommandSyntaxException e) { } catch(CommandSyntaxException e) {
throw new IllegalArgumentException(e); throw new IllegalArgumentException(e);
} }
@@ -6,7 +6,7 @@ import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.block.BlockFace; import com.dfsek.terra.api.platform.block.BlockFace;
import com.dfsek.terra.api.platform.block.BlockType; import com.dfsek.terra.api.platform.block.BlockType;
import com.dfsek.terra.api.platform.block.state.BlockState; import com.dfsek.terra.api.platform.block.state.BlockState;
import com.dfsek.terra.fabric.world.FabricAdapters; import com.dfsek.terra.fabric.world.FabricAdapter;
import com.dfsek.terra.fabric.world.handles.world.FabricWorldAccess; import com.dfsek.terra.fabric.world.handles.world.FabricWorldAccess;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.WorldAccess; import net.minecraft.world.WorldAccess;
@@ -46,12 +46,12 @@ public class FabricBlock implements Block {
@Override @Override
public boolean isEmpty() { public boolean isEmpty() {
return false; return getBlockData().isAir();
} }
@Override @Override
public Location getLocation() { public Location getLocation() {
return FabricAdapters.toVector(delegate.position).toLocation(new FabricWorldAccess(delegate.worldAccess)); return FabricAdapter.adapt(delegate.position).toLocation(new FabricWorldAccess(delegate.worldAccess));
} }
@Override @Override
@@ -2,7 +2,12 @@ package com.dfsek.terra.fabric.world.block;
import com.dfsek.terra.api.platform.block.BlockData; import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.block.BlockType; import com.dfsek.terra.api.platform.block.BlockType;
import com.dfsek.terra.fabric.mixin.StateAccessor;
import com.dfsek.terra.fabric.world.FabricAdapter;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.util.registry.Registry;
import java.util.stream.Collectors;
public class FabricBlockData implements BlockData { public class FabricBlockData implements BlockData {
protected BlockState delegate; protected BlockState delegate;
@@ -13,12 +18,12 @@ public class FabricBlockData implements BlockData {
@Override @Override
public BlockType getBlockType() { public BlockType getBlockType() {
return null; return FabricAdapter.adapt(delegate.getBlock());
} }
@Override @Override
public boolean matches(BlockData other) { public boolean matches(BlockData other) {
return false; return delegate.getBlock() == ((FabricBlockData) other).delegate.getBlock();
} }
@Override @Override
@@ -32,12 +37,18 @@ public class FabricBlockData implements BlockData {
@Override @Override
public String getAsString() { public String getAsString() {
return delegate.toString(); StringBuilder data = new StringBuilder(Registry.BLOCK.getId(delegate.getBlock()).toString());
if(!delegate.getEntries().isEmpty()) {
data.append('[');
data.append(delegate.getEntries().entrySet().stream().map(StateAccessor.getPROPERTY_MAP_PRINTER()).collect(Collectors.joining(",")));
data.append(']');
}
return data.toString();
} }
@Override @Override
public boolean isAir() { public boolean isAir() {
return false; return delegate.isAir();
} }
@Override @Override
@@ -0,0 +1,40 @@
package com.dfsek.terra.fabric.world.block;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.block.BlockType;
import com.dfsek.terra.fabric.world.FabricAdapter;
import net.minecraft.block.Block;
public class FabricBlockType implements BlockType {
private final Block delegate;
public FabricBlockType(Block delegate) {
this.delegate = delegate;
}
@Override
public Block getHandle() {
return delegate;
}
@Override
public BlockData getDefaultData() {
return FabricAdapter.adapt(delegate.getDefaultState());
}
@Override
public boolean isSolid() {
return delegate.getDefaultState().isOpaque();
}
@Override
public int hashCode() {
return delegate.hashCode();
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof FabricBlockType)) return false;
return ((FabricBlockType) obj).delegate == delegate;
}
}
@@ -3,7 +3,9 @@
"minVersion": "0.8", "minVersion": "0.8",
"package": "com.dfsek.terra.fabric.mixin", "package": "com.dfsek.terra.fabric.mixin",
"compatibilityLevel": "JAVA_8", "compatibilityLevel": "JAVA_8",
"mixins": [], "mixins": [
"StateAccessor"
],
"client": [ "client": [
"GeneratorTypeAccessor" "GeneratorTypeAccessor"
], ],
@@ -121,7 +121,7 @@ public class StandalonePlugin implements TerraPlugin {
public void register(TypeRegistry registry) { public void register(TypeRegistry registry) {
registry registry
.registerLoader(BlockData.class, (t, o, l) -> worldHandle.createBlockData((String) o)) .registerLoader(BlockData.class, (t, o, l) -> worldHandle.createBlockData((String) o))
.registerLoader(Biome.class, (t, o, l) -> new RawBiome(o.toString())) .registerLoader(Biome.class, (t, o, l) -> new RawBiome(o.toString()));
new GenericLoaders(this).register(registry); new GenericLoaders(this).register(registry);
} }