From 83cd7d360503dfca5e9641b8b9734eac04c7e0a4 Mon Sep 17 00:00:00 2001 From: RubixDev Date: Wed, 10 Mar 2021 15:02:41 +0100 Subject: [PATCH 1/5] Added netherrackGeneration rule --- .../java/com/rubixdev/rug/RugSettings.java | 6 +++ .../rubixdev/rug/mixins/FluidBlockMixin.java | 41 +++++++++++++++++++ src/main/resources/rug.mixins.json | 1 + 3 files changed, 48 insertions(+) create mode 100644 src/main/java/com/rubixdev/rug/mixins/FluidBlockMixin.java diff --git a/src/main/java/com/rubixdev/rug/RugSettings.java b/src/main/java/com/rubixdev/rug/RugSettings.java index a636582..6445165 100644 --- a/src/main/java/com/rubixdev/rug/RugSettings.java +++ b/src/main/java/com/rubixdev/rug/RugSettings.java @@ -977,6 +977,12 @@ public String description() { category = {COMMAND, RUG} ) public static String commandSkull = "ops"; + + @Rule( + desc = "Netherrack is generated instead of Cobblestone if a Magma Block is below", + category = {EXPERIMENTAL, FEATURE, SURVIVAL} + ) + public static boolean netherrackGeneration = false; } // BUGFIX diff --git a/src/main/java/com/rubixdev/rug/mixins/FluidBlockMixin.java b/src/main/java/com/rubixdev/rug/mixins/FluidBlockMixin.java new file mode 100644 index 0000000..ca05f0b --- /dev/null +++ b/src/main/java/com/rubixdev/rug/mixins/FluidBlockMixin.java @@ -0,0 +1,41 @@ +package com.rubixdev.rug.mixins; + +import com.rubixdev.rug.RugSettings; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.FluidBlock; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.WorldAccess; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(FluidBlock.class) +public abstract class FluidBlockMixin { + @Shadow protected abstract void playExtinguishSound(WorldAccess world, BlockPos pos); + + @Inject( + method = "receiveNeighborFluids", + at = @At(value = "INVOKE_ASSIGN", + target = "Lnet/minecraft/fluid/FluidState;isStill()Z"), + cancellable = true + ) + private void generateNetherrack( + World world, + BlockPos pos, + BlockState state, + CallbackInfoReturnable cir + ) { + if (RugSettings.netherrackGeneration + && world.getBlockState(pos.down()).isOf(Blocks.MAGMA_BLOCK) + && !world.getFluidState(pos).isStill() + ) { + world.setBlockState(pos, Blocks.NETHERRACK.getDefaultState()); + this.playExtinguishSound(world, pos); + cir.setReturnValue(false); + } + } +} diff --git a/src/main/resources/rug.mixins.json b/src/main/resources/rug.mixins.json index df3eb71..eb78660 100644 --- a/src/main/resources/rug.mixins.json +++ b/src/main/resources/rug.mixins.json @@ -25,6 +25,7 @@ "FallingBlockEntityMixin", "FallingBlockMixin", "FishingBobberEntityMixin", + "FluidBlockMixin", "GhastEntityMixin", "HungerManagerMixin", "ItemMixin", From 566b3057654adaf9c9d26d7e79dae8baf5d6f734 Mon Sep 17 00:00:00 2001 From: RubixDev Date: Wed, 10 Mar 2021 16:36:27 +0100 Subject: [PATCH 2/5] Added basaltToBlackstoneConversion rule --- .../java/com/rubixdev/rug/RugSettings.java | 6 ++++ .../rug/mixins/AbstractBlockMixin.java | 25 +++++++++++++++ .../rubixdev/rug/mixins/PillarBlockMixin.java | 32 +++++++++++++++++++ .../java/com/rubixdev/rug/util/Storage.java | 19 +++++++++++ src/main/resources/rug.mixins.json | 2 ++ 5 files changed, 84 insertions(+) create mode 100644 src/main/java/com/rubixdev/rug/mixins/AbstractBlockMixin.java create mode 100644 src/main/java/com/rubixdev/rug/mixins/PillarBlockMixin.java diff --git a/src/main/java/com/rubixdev/rug/RugSettings.java b/src/main/java/com/rubixdev/rug/RugSettings.java index 6445165..55f5b48 100644 --- a/src/main/java/com/rubixdev/rug/RugSettings.java +++ b/src/main/java/com/rubixdev/rug/RugSettings.java @@ -983,6 +983,12 @@ public String description() { category = {EXPERIMENTAL, FEATURE, SURVIVAL} ) public static boolean netherrackGeneration = false; + + @Rule( + desc = "Basalt converts to Blackstone if next to both Lava and Water", + category = {EXPERIMENTAL, FEATURE, SURVIVAL} + ) + public static boolean basaltToBlackstoneConversion = false; } // BUGFIX diff --git a/src/main/java/com/rubixdev/rug/mixins/AbstractBlockMixin.java b/src/main/java/com/rubixdev/rug/mixins/AbstractBlockMixin.java new file mode 100644 index 0000000..d75456f --- /dev/null +++ b/src/main/java/com/rubixdev/rug/mixins/AbstractBlockMixin.java @@ -0,0 +1,25 @@ +package com.rubixdev.rug.mixins; + +import com.rubixdev.rug.util.Storage; +import net.minecraft.block.AbstractBlock; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.WorldAccess; +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; + +@Mixin(AbstractBlock.class) +public class AbstractBlockMixin { + @Inject(method = "getStateForNeighborUpdate", at = @At("HEAD"), cancellable = true) + private void convertBasalt(BlockState state, Direction direction, BlockState newState, WorldAccess world, BlockPos pos, BlockPos posFrom, CallbackInfoReturnable cir) { + if (((Block) (Object) this).is(Blocks.BASALT) && Storage.shouldConvertBasalt(world, pos)) { + cir.setReturnValue(Blocks.BLACKSTONE.getDefaultState()); + world.syncWorldEvent(1501, pos, 0); + } + } +} diff --git a/src/main/java/com/rubixdev/rug/mixins/PillarBlockMixin.java b/src/main/java/com/rubixdev/rug/mixins/PillarBlockMixin.java new file mode 100644 index 0000000..0440220 --- /dev/null +++ b/src/main/java/com/rubixdev/rug/mixins/PillarBlockMixin.java @@ -0,0 +1,32 @@ +package com.rubixdev.rug.mixins; + +import com.rubixdev.rug.util.Storage; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.PillarBlock; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.WorldAccess; +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; + +@Mixin(PillarBlock.class) +public class PillarBlockMixin extends Block { + public PillarBlockMixin(Settings settings) { + super(settings); + } + + @Inject(method = "getPlacementState", at = @At("HEAD"), cancellable = true) + private void convertBasalt(ItemPlacementContext ctx, CallbackInfoReturnable cir) { + WorldAccess world = ctx.getWorld(); + BlockPos pos = ctx.getBlockPos(); + + if (this.is(Blocks.BASALT) && Storage.shouldConvertBasalt(world, pos)) { + cir.setReturnValue(Blocks.BLACKSTONE.getDefaultState()); + world.syncWorldEvent(1501, pos, 0); + } + } +} diff --git a/src/main/java/com/rubixdev/rug/util/Storage.java b/src/main/java/com/rubixdev/rug/util/Storage.java index 6d7cace..7007a3b 100644 --- a/src/main/java/com/rubixdev/rug/util/Storage.java +++ b/src/main/java/com/rubixdev/rug/util/Storage.java @@ -1,11 +1,30 @@ package com.rubixdev.rug.util; +import com.rubixdev.rug.RugSettings; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.fluid.Fluid; +import net.minecraft.tag.FluidTags; +import net.minecraft.tag.Tag; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.BlockView; import net.minecraft.world.World; public class Storage { public static PlayerEntity player; public static BlockPos blockPos; public static World world; + + public static boolean shouldConvertBasalt(BlockView world, BlockPos pos) { + return RugSettings.basaltToBlackstoneConversion && isFluidAdjacent(FluidTags.WATER, world, pos) && isFluidAdjacent(FluidTags.LAVA, world, pos); + } + + private static boolean isFluidAdjacent(Tag.Identified fluid, BlockView world, BlockPos pos) { + for (Direction direction : Direction.values()) { + if (world.getFluidState(pos.offset(direction)).isIn(fluid)) { + return true; + } + } + return false; + } } diff --git a/src/main/resources/rug.mixins.json b/src/main/resources/rug.mixins.json index eb78660..a7763de 100644 --- a/src/main/resources/rug.mixins.json +++ b/src/main/resources/rug.mixins.json @@ -4,6 +4,7 @@ "compatibilityLevel": "JAVA_8", "mixins": [ "AbsractBlockStateMixin", + "AbstractBlockMixin", "AbstractFurnaceBlockEntityMixin", "AbstractPlantStemBlockMixin", "AbstractRedstoneGateBlockMixin", @@ -36,6 +37,7 @@ "MobSpawnerBlockEntityMixin", "NameTagItemMixin", "NetherPortalBlockMixin", + "PillarBlockMixin", "PistonHandlerMixin", "PlayerEntityMixin", "RedstoneLampBlockMixin", From b7cc3b1f7ce1c237281eab3636006233991fc7a9 Mon Sep 17 00:00:00 2001 From: RubixDev Date: Wed, 10 Mar 2021 17:33:45 +0100 Subject: [PATCH 3/5] Improved /skull to suggest players --- .../rubixdev/rug/commands/SkullCommand.java | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/rubixdev/rug/commands/SkullCommand.java b/src/main/java/com/rubixdev/rug/commands/SkullCommand.java index ca2391d..f8eb3b6 100644 --- a/src/main/java/com/rubixdev/rug/commands/SkullCommand.java +++ b/src/main/java/com/rubixdev/rug/commands/SkullCommand.java @@ -1,6 +1,7 @@ package com.rubixdev.rug.commands; import carpet.settings.SettingsManager; +import com.google.common.collect.Sets; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.arguments.StringArgumentType; @@ -12,6 +13,11 @@ import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; +import java.util.Arrays; +import java.util.Collection; +import java.util.Set; + +import static net.minecraft.command.CommandSource.suggestMatching; import static net.minecraft.server.command.CommandManager.literal; import static net.minecraft.server.command.CommandManager.argument; @@ -19,22 +25,32 @@ public class SkullCommand { public static void register(CommandDispatcher dispatcher) { LiteralArgumentBuilder command = literal("skull"). requires((player) -> SettingsManager.canUseCommand(player, RugSettings.commandSkull)). + executes(context -> execute(context, 0)). then(argument("player", StringArgumentType.word()). - executes(context -> giveSkulls(context, 1)). + suggests(((context, builder) -> suggestMatching(getPlayers(context.getSource()), builder))). + executes(context -> execute(context, 1)). then(argument("count", IntegerArgumentType.integer(1)). - executes(context -> giveSkulls(context, context.getArgument("count", Integer.class))))); + executes(context -> execute(context, context.getArgument("count", Integer.class))))); dispatcher.register(command); } - private static int giveSkulls(CommandContext context, int count) throws CommandSyntaxException { + private static int execute(CommandContext context, int count) throws CommandSyntaxException { ServerCommandSource playerSource = context.getSource(); ServerCommandSource source = playerSource.getMinecraftServer().getCommandSource(); CommandManager manager = playerSource.getMinecraftServer().getCommandManager(); ServerPlayerEntity playerEntity = playerSource.getPlayer(); String playerName = playerEntity.getName().getString(); - String skullOwner = context.getArgument("player", String.class); + String skullOwner = count == 0 ? playerName : context.getArgument("player", String.class); + + if (count == 0) count = 1; return manager.execute(source, "give " + playerName + " minecraft:player_head{SkullOwner:" + skullOwner + "} " + count); } + + private static Collection getPlayers(ServerCommandSource source) { + Set players = Sets.newLinkedHashSet(Arrays.asList("RubixDev", "Gnembon", "Steve", "Alex")); + players.addAll(source.getPlayerNames()); + return players; + } } From a6672f87b41b85e7978aca1ad85c130372cf3b35 Mon Sep 17 00:00:00 2001 From: RubixDev Date: Wed, 10 Mar 2021 17:34:19 +0100 Subject: [PATCH 4/5] Update version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 24297a9..5018097 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ org.gradle.jvmargs=-Xmx2G carpet_core_version=1.4.23+v210115 # Mod Properties - mod_version = 1.1.4 + mod_version = 1.1.5 maven_group = com.rubixdev.rug archives_base_name = fabric-rug From 5f5c14ec2c9d1e0dea12502add12f71b0467f87e Mon Sep 17 00:00:00 2001 From: RubixDev Date: Wed, 10 Mar 2021 17:37:54 +0100 Subject: [PATCH 5/5] Update READMEs --- README.md | 18 +++++++++++++++++- markdown/EXPERIMENTAL_Category.md | 18 +++++++++++++++++- markdown/FEATURE_Category.md | 18 +++++++++++++++++- markdown/SURVIVAL_Category.md | 18 +++++++++++++++++- markdown/curseforge.md | 4 +++- 5 files changed, 71 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8c68fc6..d57aa5a 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,11 @@ Extension Mod for [gnembon's fabric-carpet](https://github.com/gnembon/fabric-ca - [`SURVIVAL`](markdown/SURVIVAL_Category.md) ## Index -Count: 69 +Count: 71 - [anvilledBlueIce](#anvilledblueice) - [anvilledIce](#anvilledice) - [anvilledPackedIce](#anvilledpackedice) +- [basaltToBlackstoneConversion](#basalttoblackstoneconversion) - [cactusFurnaceXp](#cactusfurnacexp) - [campSleeping](#campsleeping) - [commandFrame](#commandframe) @@ -63,6 +64,7 @@ Count: 69 - [maxBannerLayers](#maxbannerlayers) - [moreBarkCrafting](#morebarkcrafting) - [moreFortressSpawningBlocks](#morefortressspawningblocks) +- [netherrackGeneration](#netherrackgeneration) - [newShulkerBehavior](#newshulkerbehavior) - [noCreeperGriefing](#nocreepergriefing) - [noEndermanGriefing](#noendermangriefing) @@ -124,6 +126,13 @@ Custom amount of ice crushed by falling anvils make one packed ice. - You must choose a value from 0 to 32 - From [QuickCarpet](https://github.com/DeadlyMC/QuickCarpet114) +### basaltToBlackstoneConversion +Basalt converts to Blackstone if next to both Lava and Water +- Type: `boolean` +- Default value: `false` +- Required options: `true`, `false` +- Categories: `EXPERIMENTAL`, `FEATURE`, `SURVIVAL` + ### cactusFurnaceXp Amount of XP a Cactus smelted in a furnace gives 1 XP per Cactus seems to be a bug, as in Bedrock Edition it's only 0.2, which fits more in line with other items @@ -442,6 +451,13 @@ off: nether bricks only / more: (red) nether bricks, netherrack, soul sand/soil, - Additional notes: - [Idea from DragonEggBedrockBreaking](https://github.com/gnembon/carpet-extra/issues/182) +### netherrackGeneration +Netherrack is generated instead of Cobblestone if a Magma Block is below +- Type: `boolean` +- Default value: `false` +- Required options: `true`, `false` +- Categories: `EXPERIMENTAL`, `FEATURE`, `SURVIVAL` + ### newShulkerBehavior Makes shulkers behave like in the current 1.17 snapshots Shulkers hit by a shulker bullet have a chance to spawn a new shulker and teleport diff --git a/markdown/EXPERIMENTAL_Category.md b/markdown/EXPERIMENTAL_Category.md index 4f26d50..520c7a1 100644 --- a/markdown/EXPERIMENTAL_Category.md +++ b/markdown/EXPERIMENTAL_Category.md @@ -2,10 +2,11 @@ For a list of all implemented Rules go [here](../README.md) ## Index -Count: 30 +Count: 32 - [anvilledBlueIce](#anvilledblueice) - [anvilledIce](#anvilledice) - [anvilledPackedIce](#anvilledpackedice) +- [basaltToBlackstoneConversion](#basalttoblackstoneconversion) - [campSleeping](#campsleeping) - [dragonEggConvertsCobbleToEndstone](#dragoneggconvertscobbletoendstone) - [dragonXpDrop](#dragonxpdrop) @@ -23,6 +24,7 @@ Count: 30 - [longerRepeaters](#longerrepeaters) - [maxBannerLayers](#maxbannerlayers) - [moreFortressSpawningBlocks](#morefortressspawningblocks) +- [netherrackGeneration](#netherrackgeneration) - [newShulkerBehavior](#newshulkerbehavior) - [peacefulHunger](#peacefulhunger) - [reachDistance](#reachdistance) @@ -66,6 +68,13 @@ Custom amount of ice crushed by falling anvils make one packed ice. - You must choose a value from 0 to 32 - From [QuickCarpet](https://github.com/DeadlyMC/QuickCarpet114) +### basaltToBlackstoneConversion +Basalt converts to Blackstone if next to both Lava and Water +- Type: `boolean` +- Default value: `false` +- Required options: `true`, `false` +- Categories: `EXPERIMENTAL`, `FEATURE`, `SURVIVAL` + ### campSleeping Allows players to sleep in a Bed without setting their spawn point by entering while sneaking - Type: `boolean` @@ -215,6 +224,13 @@ off: nether bricks only / more: (red) nether bricks, netherrack, soul sand/soil, - Additional notes: - [Idea from DragonEggBedrockBreaking](https://github.com/gnembon/carpet-extra/issues/182) +### netherrackGeneration +Netherrack is generated instead of Cobblestone if a Magma Block is below +- Type: `boolean` +- Default value: `false` +- Required options: `true`, `false` +- Categories: `EXPERIMENTAL`, `FEATURE`, `SURVIVAL` + ### newShulkerBehavior Makes shulkers behave like in the current 1.17 snapshots Shulkers hit by a shulker bullet have a chance to spawn a new shulker and teleport diff --git a/markdown/FEATURE_Category.md b/markdown/FEATURE_Category.md index 73f1b5d..8449fea 100644 --- a/markdown/FEATURE_Category.md +++ b/markdown/FEATURE_Category.md @@ -2,10 +2,11 @@ For a list of all implemented Rules go [here](../README.md) ## Index -Count: 26 +Count: 28 - [anvilledBlueIce](#anvilledblueice) - [anvilledIce](#anvilledice) - [anvilledPackedIce](#anvilledpackedice) +- [basaltToBlackstoneConversion](#basalttoblackstoneconversion) - [campSleeping](#campsleeping) - [concreteConvertOnCauldron](#concreteconvertoncauldron) - [dragonDrops](#dragondrops) @@ -21,6 +22,7 @@ Count: 26 - [lilyPadsOnCauldron](#lilypadsoncauldron) - [longerRepeaters](#longerrepeaters) - [moreFortressSpawningBlocks](#morefortressspawningblocks) +- [netherrackGeneration](#netherrackgeneration) - [newShulkerBehavior](#newshulkerbehavior) - [peacefulHunger](#peacefulhunger) - [playerHeadDrops](#playerheaddrops) @@ -62,6 +64,13 @@ Custom amount of ice crushed by falling anvils make one packed ice. - You must choose a value from 0 to 32 - From [QuickCarpet](https://github.com/DeadlyMC/QuickCarpet114) +### basaltToBlackstoneConversion +Basalt converts to Blackstone if next to both Lava and Water +- Type: `boolean` +- Default value: `false` +- Required options: `true`, `false` +- Categories: `EXPERIMENTAL`, `FEATURE`, `SURVIVAL` + ### campSleeping Allows players to sleep in a Bed without setting their spawn point by entering while sneaking - Type: `boolean` @@ -185,6 +194,13 @@ off: nether bricks only / more: (red) nether bricks, netherrack, soul sand/soil, - Additional notes: - [Idea from DragonEggBedrockBreaking](https://github.com/gnembon/carpet-extra/issues/182) +### netherrackGeneration +Netherrack is generated instead of Cobblestone if a Magma Block is below +- Type: `boolean` +- Default value: `false` +- Required options: `true`, `false` +- Categories: `EXPERIMENTAL`, `FEATURE`, `SURVIVAL` + ### newShulkerBehavior Makes shulkers behave like in the current 1.17 snapshots Shulkers hit by a shulker bullet have a chance to spawn a new shulker and teleport diff --git a/markdown/SURVIVAL_Category.md b/markdown/SURVIVAL_Category.md index daf498b..64d7547 100644 --- a/markdown/SURVIVAL_Category.md +++ b/markdown/SURVIVAL_Category.md @@ -2,7 +2,8 @@ For a list of all implemented Rules go [here](../README.md) ## Index -Count: 48 +Count: 50 +- [basaltToBlackstoneConversion](#basalttoblackstoneconversion) - [cactusFurnaceXp](#cactusfurnacexp) - [campSleeping](#campsleeping) - [craftableCobwebs](#craftablecobwebs) @@ -30,6 +31,7 @@ Count: 48 - [kelpBlockHardness](#kelpblockhardness) - [maxBannerLayers](#maxbannerlayers) - [moreBarkCrafting](#morebarkcrafting) +- [netherrackGeneration](#netherrackgeneration) - [noCreeperGriefing](#nocreepergriefing) - [noEndermanGriefing](#noendermangriefing) - [noGhastGriefing](#noghastgriefing) @@ -54,6 +56,13 @@ Count: 48 ## Rules in SURVIVAL Category +### basaltToBlackstoneConversion +Basalt converts to Blackstone if next to both Lava and Water +- Type: `boolean` +- Default value: `false` +- Required options: `true`, `false` +- Categories: `EXPERIMENTAL`, `FEATURE`, `SURVIVAL` + ### cactusFurnaceXp Amount of XP a Cactus smelted in a furnace gives 1 XP per Cactus seems to be a bug, as in Bedrock Edition it's only 0.2, which fits more in line with other items @@ -283,6 +292,13 @@ Expect a lag spike when changing the value - Required options: `true`, `false` - Categories: `CRAFTING`, `RUG`, `SURVIVAL` +### netherrackGeneration +Netherrack is generated instead of Cobblestone if a Magma Block is below +- Type: `boolean` +- Default value: `false` +- Required options: `true`, `false` +- Categories: `EXPERIMENTAL`, `FEATURE`, `SURVIVAL` + ### noCreeperGriefing Prevents Creepers from destroying blocks - Type: `boolean` diff --git a/markdown/curseforge.md b/markdown/curseforge.md index 57bee56..77bd6f8 100644 --- a/markdown/curseforge.md +++ b/markdown/curseforge.md @@ -5,10 +5,11 @@ Extension Mod for [gnembon's fabric-carpet](https://github.com/gnembon/fabric-ca **Visit the [GitHub page](https://github.com/RubixDev/fabric-rug) for a more detailed explanation of all features.** ## List of implemented Carpet Rules -Count: 69 +Count: 71 - anvilledBlueIce - anvilledIce - anvilledPackedIce +- basaltToBlackstoneConversion - cactusFurnaceXp - campSleeping - commandFrame @@ -47,6 +48,7 @@ Count: 69 - maxBannerLayers - moreBarkCrafting - moreFortressSpawningBlocks +- netherrackGeneration - newShulkerBehavior - noCreeperGriefing - noEndermanGriefing