diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..784fa1d --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.gradle +.idea + +remappedSrc +out +build +run \ No newline at end of file diff --git a/src/main/java/gd/rf/acro/scf/ClientInit.java b/src/main/java/gd/rf/acro/scf/ClientInit.java deleted file mode 100644 index 42e07a6..0000000 --- a/src/main/java/gd/rf/acro/scf/ClientInit.java +++ /dev/null @@ -1,19 +0,0 @@ -package gd.rf.acro.scf; - -import net.fabricmc.api.ClientModInitializer; -import net.fabricmc.fabric.api.network.ClientSidePacketRegistry; -import net.minecraft.item.ItemStack; -import net.minecraft.sound.SoundEvents; - -public class ClientInit implements ClientModInitializer { - @Override - public void onInitializeClient() { - ClientSidePacketRegistry.INSTANCE.register(SCF.SEND_SOUND, - (packetContext, attachedData) -> { - if(attachedData.readInt()==1) - { - packetContext.getPlayer().playSound(SoundEvents.BLOCK_LAVA_EXTINGUISH,1,1); - } - }); - } -} diff --git a/src/main/java/gd/rf/acro/scf/CobblestoneFunnelBlock.java b/src/main/java/gd/rf/acro/scf/CobblestoneFunnelBlock.java deleted file mode 100644 index 953fe95..0000000 --- a/src/main/java/gd/rf/acro/scf/CobblestoneFunnelBlock.java +++ /dev/null @@ -1,173 +0,0 @@ -package gd.rf.acro.scf; - -import io.github.cottonmc.resources.BuiltinResources; -import io.github.cottonmc.resources.CottonResources; -import io.netty.buffer.Unpooled; -import net.fabricmc.fabric.api.network.ServerSidePacketRegistry; -import net.fabricmc.fabric.api.server.PlayerStream; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; -import net.minecraft.block.ShapeContext; -import net.minecraft.client.item.TooltipContext; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.network.PacketByteBuf; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.sound.SoundEvents; -import net.minecraft.tag.FluidTags; -import net.minecraft.text.LiteralText; -import net.minecraft.text.Text; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import net.minecraft.util.Identifier; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.registry.Registry; -import net.minecraft.util.shape.VoxelShape; -import net.minecraft.world.BlockView; -import net.minecraft.world.World; -import org.apache.commons.lang3.RandomUtils; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Random; - -public class CobblestoneFunnelBlock extends Block { - private int level; - private int period; - - - - public CobblestoneFunnelBlock(Settings settings, int tlevel, int tperiod) { - super(settings); - level=tlevel; - period=tperiod; - - } - - @Override - public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { - return Block.createCuboidShape(2,1,2,14,16,14); - } - - @Override - public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { - super.scheduledTick(state, world, pos, random); - if(hasLavaAndWater(pos,world) && world.getBlockState(pos.down()).isAir()) - { - PacketByteBuf packetByteBuf = new PacketByteBuf(Unpooled.buffer()); - packetByteBuf.writeInt(1); - PlayerStream.around(world,pos,5).forEach(pp->ServerSidePacketRegistry.INSTANCE.sendToPlayer(pp,SCF.SEND_SOUND,packetByteBuf)); - if(level==-1) - { - level=SCF.ORES.length; - } - long picked = RandomUtils.nextLong(0,countTotalWeights()); - System.out.println("picked: "+picked); - world.setBlockState(pos.down(),Registry.BLOCK.get(Identifier.tryParse(getOreFromBigNumber(picked))).getDefaultState()); - } - world.getBlockTickScheduler().schedule(pos,this,period); - } - - private boolean hasLavaAndWater(BlockPos pos, World world) - { - boolean hasWater = false; - boolean hasLava = false; - if(FluidTags.WATER.contains(world.getBlockState(pos.east()).getFluidState().getFluid())) - { - hasWater=true; - } - if(FluidTags.LAVA.contains(world.getBlockState(pos.east()).getFluidState().getFluid())) - { - hasLava=true; - } - - if(FluidTags.WATER.contains(world.getBlockState(pos.west()).getFluidState().getFluid())) - { - hasWater=true; - } - if(FluidTags.LAVA.contains(world.getBlockState(pos.west()).getFluidState().getFluid())) - { - hasLava=true; - } - - if(FluidTags.WATER.contains(world.getBlockState(pos.south()).getFluidState().getFluid())) - { - hasWater=true; - } - if(FluidTags.LAVA.contains(world.getBlockState(pos.south()).getFluidState().getFluid())) - { - hasLava=true; - } - - if(FluidTags.WATER.contains(world.getBlockState(pos.north()).getFluidState().getFluid())) - { - hasWater=true; - } - if(FluidTags.LAVA.contains(world.getBlockState(pos.north()).getFluidState().getFluid())) - { - hasLava=true; - } - - - return hasLava && hasWater; - } - - @Override - public void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) { - super.onPlaced(world, pos, state, placer, itemStack); - world.getBlockTickScheduler().schedule(pos,this,period); - - } - - @Override - public void buildTooltip(ItemStack stack, BlockView world, List tooltip, TooltipContext options) { - super.buildTooltip(stack, world, tooltip, options); - tooltip.add(new LiteralText("1 block every "+period/20f+" second(s)")); - if(level==-1) - { - level=SCF.ORES.length; - } - tooltip.add(new LiteralText("best block out: "+Registry.BLOCK.get(Identifier.tryParse(SCF.ORES[level-1])).getName().getString())); - tooltip.add(new LiteralText("(shift-use the block to see others!)")); - } - - @Override - public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { - if(player.isSneaking() && hand==Hand.MAIN_HAND && world.isClient) - { - for (int i = 0; i < level; i++) { - player.sendMessage(new LiteralText(Registry.BLOCK.get(Identifier.tryParse(SCF.ORES[i])).getName().getString()),false); - } - } - return super.onUse(state, world, pos, player, hand, hit); - } - - private long countTotalWeights() - { - long clap = 0; - for (int i = 0; i < level; i++) { - clap+=Integer.parseInt(SCF.WEIGHTS[i]); - } - System.out.println("total: "+clap); - return clap+1; //to include the last number - } - private String getOreFromBigNumber(long bigNumber) - { - int counter =0; - long inter = 0; - while (interbigNumber) - { - return SCF.ORES[counter]; - } - counter++; - } - return SCF.ORES[counter]; - } -} diff --git a/src/main/java/gd/rf/acro/scf/ConfigUtils.java b/src/main/java/gd/rf/acro/scf/ConfigUtils.java index 4b8b4f8..5ae0c30 100644 --- a/src/main/java/gd/rf/acro/scf/ConfigUtils.java +++ b/src/main/java/gd/rf/acro/scf/ConfigUtils.java @@ -5,95 +5,78 @@ import java.io.File; import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.nio.file.Path; +import java.util.*; public class ConfigUtils { - - public static Map config = new HashMap<>(); - - - public static Map loadConfigs() - { - File file = new File(FabricLoader.getInstance().getConfigDirectory().getPath() + "/SCF/config.acfg"); - try { - List lines = FileUtils.readLines(file,"utf-8"); - lines.forEach(line-> - { - if(line.charAt(0)!='#') - { - String noSpace = line.replace(" ",""); - String[] entry = noSpace.split("="); - config.put(entry[0],entry[1]); - } - }); - } catch (IOException e) { - e.printStackTrace(); - } - return config; - } - - public static void generateConfigs(List input) - { - File file = new File(FabricLoader.getInstance().getConfigDirectory().getPath() + "/SCF/config.acfg"); - - try { - FileUtils.writeLines(file,input); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public static Map checkConfigs() - { - if(new File(FabricLoader.getInstance().getConfigDirectory().getPath() + "/SCF/config.acfg").exists()) - { - return loadConfigs(); - } - generateConfigs(makeDefaults()); - return loadConfigs(); - } - - private static List makeDefaults() - { - List defaults = new ArrayList<>(); - defaults.add("#cobblestone funnel ore level (default 5)"); - defaults.add("cobblelvl=5"); - defaults.add("#cobblestone funnel speed (default 60)"); - defaults.add("cobblespeed=60"); - - defaults.add("#copper funnel ore level (default 9)"); - defaults.add("copperlvl=9"); - defaults.add("#copper funnel speed (default 60)"); - defaults.add("copperspeed=60"); - - defaults.add("#bronze funnel ore level (default 9)"); - defaults.add("bronzelvl=9"); - defaults.add("#bronze funnel speed (default 30)"); - defaults.add("bronzespeed=30"); - - defaults.add("#iron funnel ore level (default 14)"); - defaults.add("ironlvl=14"); - defaults.add("#iron funnel speed (default 50)"); - defaults.add("ironspeed=50"); - - defaults.add("#gold funnel ore level (default 17)"); - defaults.add("goldlvl=17"); - defaults.add("#gold funnel speed (default 40)"); - defaults.add("goldspeed=40"); - - defaults.add("#diamond funnel ore level (default -1)"); - defaults.add("diamondlvl=-1"); - defaults.add("#diamond funnel speed (default 40)"); - defaults.add("diamondspeed=40"); - - defaults.add("#netherite funnel ore level (default -1)"); - defaults.add("netheritelvl=-1"); - defaults.add("#netherite funnel speed (default 20)"); - defaults.add("netheritespeed=20"); - return defaults; - } - + public static Map config = new HashMap<>(); + private static final File file = Path.of(FabricLoader.getInstance().getConfigDirectory().getPath(), "SCF", "config.acfg").toFile(); + + public static Map loadConfigs() { + try { + FileUtils.readLines(file, "utf-8").stream() + .map(e -> e.replaceAll("\\s", "")) // remove spaces + .filter(e -> e.matches("^[^#]\\w+=\\d+$")) // is valid format + .map(e -> e.split("=")) // split arguments + .forEach(entry -> config.put(entry[0], Integer.parseInt(entry[1]))); + } catch (IOException e) { + // something went wrong with loading the files + e.printStackTrace(); + } + return config; + } + + private static void generateConfigs(List input) { + try { + FileUtils.writeLines(file, input); + } catch (IOException e) { + // something went wrong with creating the files + e.printStackTrace(); + } + } + + public static Map checkConfigs() { + if (!file.exists()) { + generateConfigs(makeDefaults()); + } + return loadConfigs(); + } + + private static List makeDefaults() { + return Arrays.asList( + "#cobblestone funnel ore level (default 0)", + "cobblelvl=0", + "#cobblestone funnel speed (default 60)", + "cobblespeed=60", + "", + "#copper funnel ore level (default 1)", + "copperlvl=1", + "#copper funnel speed (default 60)", + "copperspeed=60", + "", + "#bronze funnel ore level (default 1)", + "bronzelvl=1", + "#bronze funnel speed (default 30)", + "bronzespeed=30", + "", + "#iron funnel ore level (default 2)", + "ironlvl=2", + "#iron funnel speed (default 50)", + "ironspeed=50", + "", + "#gold funnel ore level (default 3)", + "goldlvl=3", + "#gold funnel speed (default 40)", + "goldspeed=40", + "", + "#diamond funnel ore level (default 4)", + "diamondlvl=4", + "#diamond funnel speed (default 40)", + "diamondspeed=40", + "", + "#netherite funnel ore level (default 5)", + "netheritelvl=5", + "#netherite funnel speed (default 20)", + "netheritespeed=20"); + } } diff --git a/src/main/java/gd/rf/acro/scf/FunnelBlock.java b/src/main/java/gd/rf/acro/scf/FunnelBlock.java new file mode 100644 index 0000000..3d5fcc4 --- /dev/null +++ b/src/main/java/gd/rf/acro/scf/FunnelBlock.java @@ -0,0 +1,148 @@ +package gd.rf.acro.scf; + +import gd.rf.acro.scf.mixin.WeightedListAccessor; +import gd.rf.acro.scf.mixin.WeightedListEntryAccessor; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.item.TooltipContext; +import net.minecraft.client.options.GameOptions; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.fluid.Fluid; +import net.minecraft.item.ItemStack; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; +import net.minecraft.tag.FluidTags; +import net.minecraft.text.*; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.Identifier; +import net.minecraft.util.collection.WeightedList; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.registry.Registry; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.world.BlockView; +import net.minecraft.world.World; + +import java.util.Comparator; +import java.util.List; +import java.util.Random; + +public class FunnelBlock extends Block { + private final static VoxelShape SHAPE = Block.createCuboidShape(2, 1, 2, 14, 16, 14); + private final int period; + private int tier; + + public FunnelBlock(Settings settings, int tier, int period) { + super(settings); + this.tier = tier; + this.period = period; + + if (this.tier < 0 || this.tier >= OreManager.weightedListCollection.size()) { // makes sure tier doesn't exceed bounds + this.tier = MathHelper.clamp(this.tier, 0, OreManager.weightedListCollection.size() - 1); + } + } + + @Override + @SuppressWarnings("deprecation") + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return SHAPE; // storing an object in memory is faster + } + + @Override + @SuppressWarnings("deprecation") + public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { + super.scheduledTick(state, world, pos, random); + + if (hasLavaAndWater(pos, world) && world.getBlockState(pos.down()).isAir()) { + if (!world.isClient) { + // playing sound is build in by mojang + world.playSound(null, pos, SoundEvents.BLOCK_LAVA_EXTINGUISH, SoundCategory.BLOCKS, 1, 1); + } + + Identifier randomBlockId = OreManager.weightedListCollection.get(this.tier).pickRandom(random); + world.setBlockState(pos.down(), Registry.BLOCK.get(randomBlockId).getDefaultState()); + } + world.getBlockTickScheduler().schedule(pos, this, this.period); + } + + private boolean hasLavaAndWater(BlockPos pos, World world) { + Direction.Type offsets = Direction.Type.HORIZONTAL; + + boolean hasWater = offsets.stream().anyMatch(e -> FluidTags.WATER.contains(this.getFluidAtPos(pos.offset(e), world))); + boolean hasLava = offsets.stream().anyMatch(e -> FluidTags.LAVA.contains(this.getFluidAtPos(pos.offset(e), world))); + + return hasLava && hasWater; + } + + /** + * Returns fluid at the given position + * @param pos The position to check + * @param world The world to check in + * @return The fluid at the given position + */ + private Fluid getFluidAtPos(BlockPos pos, World world) { + return world.getBlockState(pos).getFluidState().getFluid(); + } + + @Override + public void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) { + super.onPlaced(world, pos, state, placer, itemStack); + world.getBlockTickScheduler().schedule(pos, this, this.period); + } + + @Override + public void buildTooltip(ItemStack stack, BlockView world, List tooltip, TooltipContext options) { + if (world != null) { // prevents many calls to this method during startup + super.buildTooltip(stack, world, tooltip, options); + + Identifier id = this.getGreatestWeight(); + GameOptions gameOptions = MinecraftClient.getInstance().options; + + // uses translatable texts for multi-lang support + tooltip.add(new TranslatableText("util.scf.blocks_per_second", this.period / 20f)); + tooltip.add(new TranslatableText("util.scf.best_block", Registry.BLOCK.get(id).getName())); + tooltip.add(new TranslatableText("util.scf.extra_info", + new TranslatableText(gameOptions.keySneak.getTranslationKey()), + new TranslatableText(gameOptions.keyUse.getTranslationKey()) + )); + } + } + + @Override + @SuppressWarnings("deprecation") + public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + if (player.isSneaking() && hand == Hand.MAIN_HAND && world.isClient) { + // uses translatable texts for multi-lang support + MutableText text = new TranslatableText("util.scf.funnel_output"); + this.getList().stream().forEach(e -> text.append(new LiteralText("\n ")) + .append(Registry.BLOCK.get(e).getName())); // puts each entry on a new line slightly indented + + player.sendMessage(text, false); + } + return super.onUse(state, world, pos, player, hand, hit); + } + + private WeightedList getList() { + return OreManager.weightedListCollection.get(this.tier); + } + + /** + * Gets the identifier of the block with the biggest weight for this tier + * + * @return The identifier of the block with the biggest weight for this tier + */ + private Identifier getGreatestWeight() { + return ((WeightedListAccessor) this.getList()).getEntries().stream() + .sorted(Comparator.comparing(WeightedList.Entry::getElement)) + .min(Comparator.comparingInt(e -> ((WeightedListEntryAccessor) e).getWeight())) + .map(WeightedList.Entry::getElement) + .orElse(null); + } +} diff --git a/src/main/java/gd/rf/acro/scf/OreManager.java b/src/main/java/gd/rf/acro/scf/OreManager.java new file mode 100644 index 0000000..928609e --- /dev/null +++ b/src/main/java/gd/rf/acro/scf/OreManager.java @@ -0,0 +1,139 @@ +package gd.rf.acro.scf; + +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.util.Identifier; +import net.minecraft.util.InvalidIdentifierException; +import net.minecraft.util.collection.WeightedList; +import org.apache.commons.io.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class OreManager { + public static final List> weightedListCollection = new ArrayList<>(); + private static final String[] DEFAULT_ORES = { + // ore/tag, funnel tier, weight + "minecraft:cobblestone,0,100", + "minecraft:stone,0,100", + "minecraft:coal_ore,0,100", + "c:tin_ore,0,100", + "c:copper_ore,0,100", + "minecraft:iron_ore,1,100", + "c:zinc_ore,1,100", + "c:aluminum_ore,1,100", + "c:lead_ore,1,100", + "c:silver_ore,2,100", + "minecraft:redstone_ore,2,100", + "minecraft:nether_quartz_ore,2,100", + "minecraft:gold_ore,2,100", + "c:uranium_ore,2,100", + "minecraft:diamond_ore,3,20", + "c:platinum_ore,3,20", + "c:tungsten_ore,3,20", + "c:osmium_ore,4,20", + "c:palladium_ore,4,20", + "c:amethyst_ore,4,20", + "c:iridium_ore,4,20", + "c:topaz_ore,4,20", + "c:cobalt_ore,4,20", + "c:peridot_ore,4,20", + "c:sapphire_ore,4,20", + "c:ruby_ore,4,20", + "minecraft:ancient_debris,4,1" + }; + + public static void makeOreTable() { + File file = Path.of(FabricLoader.getInstance().getConfigDirectory().getPath(), "SCF", "ores.acfg").toFile(); + + // write default values if no file exists + if (!file.exists()) { + try { + FileUtils.writeLines(file, Arrays.asList(DEFAULT_ORES)); + } catch (IOException e) { + // something went wrong with creating the files + e.printStackTrace(); + } + } + + try { + List lines = FileUtils.readLines(file, "utf-8"); + + // load all data + lines.parallelStream() + .map(e -> e.replaceAll("\\s", "")) // remove spaces + .filter(e -> e.matches("([a-z0-9_.-]+:)?[a-z0-9_.-]+,\\d+,\\d+")) // is valid format + .map(e -> e.split(",")) // split arguments + .sorted((a, b) -> -a[1].compareTo(b[1])) // sort it so that highest tier is done first + .forEachOrdered(OreManager::setWeights); + + // let user know if the config format was wrong + lines.parallelStream() + .map(e -> e.replace("\\s", "")) // remove spaces + .filter(e -> !e.matches("([a-z0-9_.-]+:)?[a-z0-9_.-]+,\\d+,\\d+")) // is not valid format + .forEachOrdered(e -> { + SCF.LOGGER.warning("invalid format"); + SCF.LOGGER.warning(e); + }); + } catch (IOException e) { + // something went wrong with loading the files + e.printStackTrace(); + } + } + + /** + * A helper to set all the weights + * Must be called with the highest tier first + * + * @param ctx The params for this value, in the order [Identifier, tier, weight] + */ + private static void setWeights(String[] ctx) { + Identifier id; + int tier; + int weight; + + try { + id = new Identifier(ctx[0]); + } catch (InvalidIdentifierException e) { + // shouldn't happen with regex check + SCF.LOGGER.warning("invalid config identifier"); + SCF.LOGGER.warning("[" + ctx[0] + "], " + ctx[1] + ", " + ctx[2]); + return; + } + + try { + tier = Integer.parseInt(ctx[1]); + + if (tier < 0) { + throw new NumberFormatException(); // get into the catch + } + } catch (NumberFormatException e) { + // shouldn't happen with regex check + SCF.LOGGER.warning("invalid tier number"); + SCF.LOGGER.warning(ctx[0] + ", [" + ctx[1] + "], " + ctx[2]); + return; + } + + try { + weight = Integer.parseInt(ctx[2]); + } catch (NumberFormatException e) { + // shouldn't happen with regex check + SCF.LOGGER.warning("invalid weight number"); + SCF.LOGGER.warning(ctx[0] + ", " + ctx[1] + ", [" + ctx[2] + "]"); + return; + } + + // add new lists if they don't exist yet + for (int i = weightedListCollection.size(); i <= tier; i++) { + weightedListCollection.add(new WeightedList<>()); + } + + // fill the list with their weights + for (int i = tier; i < weightedListCollection.size(); i++) { + weightedListCollection.get(i).add(id, weight); + } + } +} diff --git a/src/main/java/gd/rf/acro/scf/SCF.java b/src/main/java/gd/rf/acro/scf/SCF.java index 6c5b02b..9d9289b 100644 --- a/src/main/java/gd/rf/acro/scf/SCF.java +++ b/src/main/java/gd/rf/acro/scf/SCF.java @@ -2,165 +2,69 @@ import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder; -import net.fabricmc.loader.api.FabricLoader; import net.minecraft.block.AbstractBlock; +import net.minecraft.block.Block; import net.minecraft.block.Material; import net.minecraft.item.BlockItem; import net.minecraft.item.Item; import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; -import net.minecraft.loot.LootTables; import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; -import org.apache.commons.io.FileUtils; -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.logging.Logger; public class SCF implements ModInitializer { - public static final Identifier SEND_SOUND = new Identifier("scf","send_sound"); - public static String[] ORES = {}; - public static String[] WEIGHTS = {}; + public static final Logger LOGGER = Logger.getLogger("SCF"); + + public static Block COBBLESTONE_FUNNEL_BLOCK; + public static Block COPPER_FUNNEL_BLOCK; + public static Block BRONZE_FUNNEL_BLOCK; + public static Block IRON_FUNNEL_BLOCK; + public static Block GOLD_FUNNEL_BLOCK; + public static Block DIAMOND_FUNNEL_BLOCK; + public static Block NETHERITE_FUNNEL_BLOCK; + public static final ItemGroup TAB = FabricItemGroupBuilder.build( new Identifier("scf", "tab"), () -> new ItemStack(SCF.COBBLESTONE_FUNNEL_BLOCK)); + @Override public void onInitialize() { - // This code runs as soon as Minecraft is in a mod-load-ready state. - // However, some things (like resources) may still be uninitialized. - // Proceed with mild caution. ConfigUtils.checkConfigs(); - registerBlocks(); - registerItems(); - readOreTable(); - System.out.println("Hello Fabric world!"); - } - public static CobblestoneFunnelBlock COBBLESTONE_FUNNEL_BLOCK; - public static CobblestoneFunnelBlock COPPER_FUNNEL_BLOCK; - public static CobblestoneFunnelBlock BRONZE_FUNNEL_BLOCK; - public static CobblestoneFunnelBlock IRON_FUNNEL_BLOCK; - public static CobblestoneFunnelBlock GOLD_FUNNEL_BLOCK; - public static CobblestoneFunnelBlock DIAMOND_FUNNEL_BLOCK; - public static CobblestoneFunnelBlock NETHERITE_FUNNEL_BLOCK; - private void registerBlocks() - { - Map c = ConfigUtils.config; - COBBLESTONE_FUNNEL_BLOCK = new CobblestoneFunnelBlock(AbstractBlock.Settings.of(Material.STONE).ticksRandomly().strength(1.5f,0),Integer.parseInt(c.get("cobblelvl")),Integer.parseInt(c.get("cobblespeed"))); - COPPER_FUNNEL_BLOCK = new CobblestoneFunnelBlock(AbstractBlock.Settings.of(Material.STONE).ticksRandomly().strength(1.5f,0),Integer.parseInt(c.get("copperlvl")),Integer.parseInt(c.get("copperspeed"))); - BRONZE_FUNNEL_BLOCK = new CobblestoneFunnelBlock(AbstractBlock.Settings.of(Material.STONE).ticksRandomly().strength(1.5f,0),Integer.parseInt(c.get("bronzelvl")),Integer.parseInt(c.get("bronzespeed"))); - IRON_FUNNEL_BLOCK = new CobblestoneFunnelBlock(AbstractBlock.Settings.of(Material.STONE).ticksRandomly().strength(1.5f,0),Integer.parseInt(c.get("ironlvl")),Integer.parseInt(c.get("ironspeed"))); - GOLD_FUNNEL_BLOCK = new CobblestoneFunnelBlock(AbstractBlock.Settings.of(Material.STONE).ticksRandomly().strength(1.5f,0),Integer.parseInt(c.get("goldlvl")),Integer.parseInt(c.get("goldspeed"))); - DIAMOND_FUNNEL_BLOCK = new CobblestoneFunnelBlock(AbstractBlock.Settings.of(Material.STONE).ticksRandomly().strength(1.5f,0),Integer.parseInt(c.get("diamondlvl")),Integer.parseInt(c.get("diamondspeed"))); - NETHERITE_FUNNEL_BLOCK = new CobblestoneFunnelBlock(AbstractBlock.Settings.of(Material.STONE).ticksRandomly().strength(1.5f,0),Integer.parseInt(c.get("netheritelvl")),Integer.parseInt(c.get("netheritespeed"))); - - + OreManager.makeOreTable(); - Registry.register(Registry.BLOCK,new Identifier("scf","cobblestone_funnel"),COBBLESTONE_FUNNEL_BLOCK); - Registry.register(Registry.BLOCK,new Identifier("scf","copper_funnel"),COPPER_FUNNEL_BLOCK); - Registry.register(Registry.BLOCK,new Identifier("scf","bronze_funnel"),BRONZE_FUNNEL_BLOCK); - Registry.register(Registry.BLOCK,new Identifier("scf","iron_funnel"),IRON_FUNNEL_BLOCK); - Registry.register(Registry.BLOCK,new Identifier("scf","gold_funnel"),GOLD_FUNNEL_BLOCK); - Registry.register(Registry.BLOCK,new Identifier("scf","diamond_funnel"),DIAMOND_FUNNEL_BLOCK); - Registry.register(Registry.BLOCK,new Identifier("scf","netherite_funnel"),NETHERITE_FUNNEL_BLOCK); + COBBLESTONE_FUNNEL_BLOCK = registerFunnel("cobblestone_funnel", "cobblelvl", "cobblespeed"); + COPPER_FUNNEL_BLOCK = registerFunnel("copper_funnel", "copperlvl", "copperspeed"); + BRONZE_FUNNEL_BLOCK = registerFunnel("bronze_funnel", "bronzelvl", "bronzespeed"); + IRON_FUNNEL_BLOCK = registerFunnel("iron_funnel", "ironlvl", "ironspeed"); + GOLD_FUNNEL_BLOCK = registerFunnel("gold_funnel", "goldlvl", "goldspeed"); + DIAMOND_FUNNEL_BLOCK = registerFunnel("diamond_funnel", "diamondlvl", "diamondspeed"); + NETHERITE_FUNNEL_BLOCK = registerFunnel("netherite_funnel", "netheritelvl", "netheritespeed"); } - private void registerItems() - { - Registry.register(Registry.ITEM,new Identifier("scf","cobblestone_funnel"),new BlockItem(COBBLESTONE_FUNNEL_BLOCK,new Item.Settings().group(TAB))); - Registry.register(Registry.ITEM,new Identifier("scf","copper_funnel"),new BlockItem(COPPER_FUNNEL_BLOCK,new Item.Settings().group(TAB))); - Registry.register(Registry.ITEM,new Identifier("scf","bronze_funnel"),new BlockItem(BRONZE_FUNNEL_BLOCK,new Item.Settings().group(TAB))); - Registry.register(Registry.ITEM,new Identifier("scf","iron_funnel"),new BlockItem(IRON_FUNNEL_BLOCK,new Item.Settings().group(TAB))); - Registry.register(Registry.ITEM,new Identifier("scf","gold_funnel"),new BlockItem(GOLD_FUNNEL_BLOCK,new Item.Settings().group(TAB))); - Registry.register(Registry.ITEM,new Identifier("scf","diamond_funnel"),new BlockItem(DIAMOND_FUNNEL_BLOCK,new Item.Settings().group(TAB))); - Registry.register(Registry.ITEM,new Identifier("scf","netherite_funnel"),new BlockItem(NETHERITE_FUNNEL_BLOCK,new Item.Settings().group(TAB))); - } - - private void readOreTable() - { - File file = new File(FabricLoader.getInstance().getConfigDirectory().getPath() + "/SCF/funnel_blocks.acfg"); - File file2 = new File(FabricLoader.getInstance().getConfigDirectory().getPath() + "/SCF/funnel_blocks_weights.acfg"); - try - { - if(!file.exists()) - { - FileUtils.writeLines(file, Arrays.asList(cRES)); - } - ORES= FileUtils.readLines(file,"utf-8").toArray(ORES); - - if(!file2.exists()) - { - FileUtils.writeLines(file2, Arrays.asList(cResRolls)); - } - WEIGHTS= FileUtils.readLines(file2,"utf-8").toArray(WEIGHTS); - } catch (IOException e) { - e.printStackTrace(); - } - } - - private static final String[] cRES = - { - "minecraft:cobblestone", - "minecraft:stone", - "minecraft:coal_ore", - "c:tin_ore", - "c:copper_ore", - "minecraft:iron_ore", - "c:zinc_ore", - "c:aluminum_ore", - "c:lead_ore", - "c:silver_ore", - "minecraft:redstone_ore", - "minecraft:nether_quartz_ore", - "minecraft:gold_ore", - "c:uranium_ore", - "minecraft:diamond_ore", - "c:platinum_ore", - "c:tungsten_ore", - "c:osmium_ore", - "c:palladium_ore", - "c:amethyst_ore", - "c:iridium_ore", - "c:topaz_ore", - "c:cobalt_ore", - "c:peridot_ore", - "c:sapphire_ore", - "c:ruby_ore", - "minecraft:ancient_debris", - }; + /** + * Helper method for creating a funnel block and item + * + * @param id The id of the funnel, with a default namespace of scf + * @param tier The name of the tier according to the config + * @param speed The speed the funnel generates blocks, in seconds + * @return The created block + */ + private FunnelBlock registerFunnel(String id, String tier, String speed) { + FunnelBlock block = Registry.register(Registry.BLOCK, + new Identifier("scf", id), + new FunnelBlock( + AbstractBlock.Settings + .of(Material.STONE) + .ticksRandomly() + .strength(1.5f, 0), + ConfigUtils.config.get(tier), ConfigUtils.config.get(speed))); - private static final String[] cResRolls = - { - "100", - "100", - "100", - "100", - "100", - "100", - "100", - "100", - "100", - "100", - "100", - "100", - "100", - "100", - "20", - "20", - "20", - "20", - "20", - "20", - "20", - "20", - "20", - "20", - "20", - "20", - "1" + Registry.register(Registry.ITEM, + new Identifier("scf", id), + new BlockItem(block, new Item.Settings().group(TAB))); - }; + return block; + } } diff --git a/src/main/java/gd/rf/acro/scf/mixin/WeightedListAccessor.java b/src/main/java/gd/rf/acro/scf/mixin/WeightedListAccessor.java new file mode 100644 index 0000000..f686780 --- /dev/null +++ b/src/main/java/gd/rf/acro/scf/mixin/WeightedListAccessor.java @@ -0,0 +1,13 @@ +package gd.rf.acro.scf.mixin; + +import net.minecraft.util.collection.WeightedList; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.List; + +@Mixin(WeightedList.class) +public interface WeightedListAccessor { + @Accessor + List> getEntries(); +} diff --git a/src/main/java/gd/rf/acro/scf/mixin/WeightedListEntryAccessor.java b/src/main/java/gd/rf/acro/scf/mixin/WeightedListEntryAccessor.java new file mode 100644 index 0000000..c7a63eb --- /dev/null +++ b/src/main/java/gd/rf/acro/scf/mixin/WeightedListEntryAccessor.java @@ -0,0 +1,11 @@ +package gd.rf.acro.scf.mixin; + +import net.minecraft.util.collection.WeightedList; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(WeightedList.Entry.class) +public interface WeightedListEntryAccessor { + @Accessor + int getWeight(); +} diff --git a/src/main/resources/assets/scf/lang/en_us.json b/src/main/resources/assets/scf/lang/en_us.json index bb1f854..88d2fa6 100644 --- a/src/main/resources/assets/scf/lang/en_us.json +++ b/src/main/resources/assets/scf/lang/en_us.json @@ -6,5 +6,9 @@ "block.scf.diamond_funnel": "Diamond Funnel", "block.scf.bronze_funnel": "Bronze Funnel", "block.scf.netherite_funnel": "Netherite Funnel", - "itemGroup.scf.tab": "Super Cobblestone Funnels" + "itemGroup.scf.tab": "Super Cobblestone Funnels", + "util.scf.funnel_output": "Possible blocks that get generated:", + "util.scf.blocks_per_second": "1 block every %f second(s)", + "util.scf.best_block": "best block out: %s", + "util.scf.extra_info": "(%s-%s the block to see others!)" } \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index b91f32e..c159a2a 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -20,8 +20,7 @@ "entrypoints": { "main": [ "gd.rf.acro.scf.SCF" - ], - "client": ["gd.rf.acro.scf.ClientInit"] + ] }, "mixins": [ "modid.mixins.json" diff --git a/src/main/resources/modid.mixins.json b/src/main/resources/modid.mixins.json index 36473e2..ac180ac 100644 --- a/src/main/resources/modid.mixins.json +++ b/src/main/resources/modid.mixins.json @@ -4,6 +4,8 @@ "package": "gd.rf.acro.scf.mixin", "compatibilityLevel": "JAVA_8", "mixins": [ + "WeightedListAccessor", + "WeightedListEntryAccessor" ], "client": [ ],