diff --git a/gradle.properties b/gradle.properties index 99d343f..8a1c950 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false -mod_version = 3.0 +mod_version = 3.1 artifact_minecraft_version = 1.19.2 minecraft_version = 1.19.2 diff --git a/src/main/java/nl/requios/effortlessbuilding/ClientEvents.java b/src/main/java/nl/requios/effortlessbuilding/ClientEvents.java index df08e11..4da00d4 100644 --- a/src/main/java/nl/requios/effortlessbuilding/ClientEvents.java +++ b/src/main/java/nl/requios/effortlessbuilding/ClientEvents.java @@ -37,12 +37,9 @@ public class ClientEvents { @SubscribeEvent public static void registerKeyMappings(RegisterKeyMappingsEvent event) { - EffortlessBuilding.log("Registering KeyMappings!"); - // register key bindings keyBindings = new KeyMapping[6]; - // instantiate the key bindings keyBindings[0] = new KeyMapping("key.effortlessbuilding.mode.desc", KeyConflictContext.IN_GAME, InputConstants.getKey(GLFW.GLFW_KEY_LEFT_ALT, 0), "key.effortlessbuilding.category"); keyBindings[1] = new KeyMapping("key.effortlessbuilding.hud.desc", KeyConflictContext.IN_GAME, InputConstants.getKey(GLFW.GLFW_KEY_KP_ADD, 0), "key.effortlessbuilding.category"); keyBindings[2] = new KeyMapping("key.effortlessbuilding.undo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, InputConstants.getKey(GLFW.GLFW_KEY_Z, 0), "key.effortlessbuilding.category"); diff --git a/src/main/java/nl/requios/effortlessbuilding/CommonConfig.java b/src/main/java/nl/requios/effortlessbuilding/CommonConfig.java index 7fa8541..e3509a5 100644 --- a/src/main/java/nl/requios/effortlessbuilding/CommonConfig.java +++ b/src/main/java/nl/requios/effortlessbuilding/CommonConfig.java @@ -29,7 +29,7 @@ public class CommonConfig { level0 = builder .comment("Maximum reach in survival without upgrades", - "Consume Power Level upgrades upgrades to permanently increase this.") + "Consume Power Level upgrades to permanently increase this.") .defineInRange("reachLevel0", 0, 0, 1000); level1 = builder @@ -61,7 +61,7 @@ public class CommonConfig { level0 = builder .comment("In survival without upgrades", - "Consume Power Level upgrades upgrades to permanently increase this.", + "Consume Power Level upgrades to permanently increase this.", "Set to 0 to disable Effortless Building until the player has increased their Building Power Level.") .defineInRange("maxBlocksPlacedAtOnceLevel0", 128, 0, 100000); @@ -89,12 +89,13 @@ public class CommonConfig { builder.push("MaxBlocksPerAxis"); creative = builder - .comment("How many blocks can be placed at once per axis.") + .comment("How many blocks can be placed at once per axis when using build modes (e.g. walls).", + "Also affects the array modifier.") .defineInRange("maxBlocksPerAxisCreative", 1000, 0, 1000); level0 = builder .comment("In survival without upgrades", - "Consume Power Level upgrades upgrades to permanently increase this.") + "Consume Power Level upgrades to permanently increase this.") .defineInRange("maxBlocksPerAxisLevel0", 8, 0, 1000); level1 = builder diff --git a/src/main/java/nl/requios/effortlessbuilding/CommonEvents.java b/src/main/java/nl/requios/effortlessbuilding/CommonEvents.java index e573bb1..eaf2ffe 100644 --- a/src/main/java/nl/requios/effortlessbuilding/CommonEvents.java +++ b/src/main/java/nl/requios/effortlessbuilding/CommonEvents.java @@ -68,7 +68,7 @@ public class CommonEvents { //Don't cancel event if our custom logic is breaking blocks if (EffortlessBuilding.SERVER_BLOCK_PLACER.isPlacingOrBreakingBlocks()) return; - if (!ServerBuildState.isLikeVanilla(player) && PowerLevel.canBreakFar(player)) { + if (!ServerBuildState.isLikeVanilla(player) && EffortlessBuilding.SERVER_POWER_LEVEL.canBreakFar(player)) { event.setCanceled(true); } } @@ -88,6 +88,7 @@ public class CommonEvents { ServerBuildState.handleNewPlayer(player); PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new ModifierSettingsPacket(player)); + EffortlessBuilding.SERVER_POWER_LEVEL.sendToClient(player); } @SubscribeEvent diff --git a/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java b/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java index 464eaf7..e5d4992 100644 --- a/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java +++ b/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java @@ -1,5 +1,6 @@ package nl.requios.effortlessbuilding; +import com.mojang.serialization.Codec; import net.minecraft.network.chat.Component; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; @@ -7,6 +8,7 @@ import net.minecraft.world.inventory.MenuType; import net.minecraft.world.item.Item; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.loot.IGlobalLootModifier; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.ModLoadingContext; @@ -29,6 +31,7 @@ import nl.requios.effortlessbuilding.proxy.IProxy; import nl.requios.effortlessbuilding.proxy.ServerProxy; import nl.requios.effortlessbuilding.systems.ItemUsageTracker; import nl.requios.effortlessbuilding.systems.ServerBlockPlacer; +import nl.requios.effortlessbuilding.systems.ServerPowerLevel; import nl.requios.effortlessbuilding.systems.UndoRedo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -45,10 +48,12 @@ public class EffortlessBuilding { public static final ServerBlockPlacer SERVER_BLOCK_PLACER = new ServerBlockPlacer(); public static final UndoRedo UNDO_REDO = new UndoRedo(); public static final ItemUsageTracker ITEM_USAGE_TRACKER = new ItemUsageTracker(); + public static final ServerPowerLevel SERVER_POWER_LEVEL = new ServerPowerLevel(); //Registration private static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MODID); private static final DeferredRegister> CONTAINERS = DeferredRegister.create(ForgeRegistries.MENU_TYPES, EffortlessBuilding.MODID); + public static final DeferredRegister> LOOT_MODIFIERS = DeferredRegister.create(ForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, EffortlessBuilding.MODID); public static final RegistryObject RANDOMIZER_BAG_ITEM = ITEMS.register("randomizer_bag", RandomizerBagItem::new); public static final RegistryObject GOLDEN_RANDOMIZER_BAG_ITEM = ITEMS.register("golden_randomizer_bag", GoldenRandomizerBagItem::new); @@ -56,11 +61,15 @@ public class EffortlessBuilding { public static final RegistryObject REACH_UPGRADE_1_ITEM = ITEMS.register("reach_upgrade1", ReachUpgrade1Item::new); public static final RegistryObject REACH_UPGRADE_2_ITEM = ITEMS.register("reach_upgrade2", ReachUpgrade2Item::new); public static final RegistryObject REACH_UPGRADE_3_ITEM = ITEMS.register("reach_upgrade3", ReachUpgrade3Item::new); + public static final RegistryObject MUSCLES_ITEM = ITEMS.register("muscles", PowerLevelItem::new); + public static final RegistryObject ELASTIC_HAND_ITEM = ITEMS.register("elastic_hand", PowerLevelItem::new); + public static final RegistryObject BUILDING_TECHNIQUES_BOOK_ITEM = ITEMS.register("building_techniques_book", PowerLevelItem::new); public static final RegistryObject> RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("randomizer_bag", () -> registerContainer(RandomizerBagContainer::new)); public static final RegistryObject> GOLDEN_RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("golden_randomizer_bag", () -> registerContainer(GoldenRandomizerBagContainer::new)); public static final RegistryObject> DIAMOND_RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("diamond_randomizer_bag", () -> registerContainer(DiamondRandomizerBagContainer::new)); + public EffortlessBuilding() { instance = this; @@ -75,6 +84,9 @@ public class EffortlessBuilding { ITEMS.register(FMLJavaModLoadingContext.get().getModEventBus()); CONTAINERS.register(FMLJavaModLoadingContext.get().getModEventBus()); + var singleItemLootModifier = SingleItemLootModifier.CODEC; //load this class to register the loot modifier + LOOT_MODIFIERS.register(FMLJavaModLoadingContext.get().getModEventBus()); + //Register config ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, CommonConfig.spec); ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, ClientConfig.spec); diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java b/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java index 2be32d4..6383771 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java @@ -144,13 +144,17 @@ public class RadialMenu extends Screen { } //Add actions + boolean canReplace = Minecraft.getInstance().player != null && EffortlessBuildingClient.POWER_LEVEL.canReplaceBlocks(Minecraft.getInstance().player); + // buttons.add(new MenuButton(ActionEnum.OPEN_PLAYER_SETTINGS, -buttonDistance - 65, -13, Direction.UP)); - buttons.add(new MenuButton(ActionEnum.TOGGLE_PROTECT_TILE_ENTITIES, -buttonDistance - 78, -13, Direction.UP)); + if (canReplace) { + buttons.add(new MenuButton(ActionEnum.TOGGLE_PROTECT_TILE_ENTITIES, -buttonDistance - 78, -13, Direction.UP)); + } buttons.add(new MenuButton(ActionEnum.OPEN_MODIFIER_SETTINGS, -buttonDistance - 52, -13, Direction.UP)); buttons.add(new MenuButton(ActionEnum.UNDO, -buttonDistance - 26, -13, Direction.UP)); buttons.add(new MenuButton(ActionEnum.REDO, -buttonDistance, -13, Direction.UP)); - if (Minecraft.getInstance().player != null && PowerLevel.canReplaceBlocks(Minecraft.getInstance().player)) { + if (canReplace) { buttons.add(new MenuButton(ActionEnum.REPLACE_ONLY_AIR, -buttonDistance - 78, 13, Direction.DOWN)); buttons.add(new MenuButton(ActionEnum.REPLACE_BLOCKS_AND_AIR, -buttonDistance - 52, 13, Direction.DOWN)); buttons.add(new MenuButton(ActionEnum.REPLACE_ONLY_BLOCKS, -buttonDistance - 26, 13, Direction.DOWN)); diff --git a/src/main/java/nl/requios/effortlessbuilding/item/PowerLevelItem.java b/src/main/java/nl/requios/effortlessbuilding/item/PowerLevelItem.java new file mode 100644 index 0000000..ec4400f --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/item/PowerLevelItem.java @@ -0,0 +1,56 @@ +package nl.requios.effortlessbuilding.item; + +import net.minecraft.ChatFormatting; +import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.network.chat.Component; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.level.Level; +import nl.requios.effortlessbuilding.EffortlessBuilding; +import nl.requios.effortlessbuilding.EffortlessBuildingClient; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.List; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class PowerLevelItem extends Item { + public PowerLevelItem() { + super(new Item.Properties().tab(CreativeModeTab.TAB_TOOLS)); + } + + @Override + public InteractionResultHolder use(Level world, Player player, InteractionHand hand) { + + if (world.isClientSide){ + + if (EffortlessBuildingClient.POWER_LEVEL.canIncreasePowerLevel()) { + + EffortlessBuildingClient.POWER_LEVEL.increasePowerLevel(); + EffortlessBuilding.log(player, "Upgraded power level to " + EffortlessBuildingClient.POWER_LEVEL.getPowerLevel()); + player.setItemInHand(hand, ItemStack.EMPTY); + return InteractionResultHolder.consume(player.getItemInHand(hand)); + + } else { + + EffortlessBuilding.log(player, "Already reached maximum power level!"); + return InteractionResultHolder.fail(player.getItemInHand(hand)); + } + + } else { + return InteractionResultHolder.consume(player.getItemInHand(hand)); + } + } + + @Override + public void appendHoverText(ItemStack stack, @Nullable Level world, List tooltip, TooltipFlag isAdvanced) { + tooltip.add(Component.translatable(getDescriptionId() + ".desc").withStyle(ChatFormatting.GRAY)); + tooltip.add(Component.translatable("key.effortlessbuilding.upgrade_power_level").withStyle(ChatFormatting.BLUE)); + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade1Item.java b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade1Item.java index 6bcd807..767eb58 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade1Item.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade1Item.java @@ -20,7 +20,6 @@ import java.util.List; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResultHolder; @ParametersAreNonnullByDefault @@ -36,12 +35,12 @@ public class ReachUpgrade1Item extends Item { if (player.isCreative()) { if (world.isClientSide) EffortlessBuilding.log(player, "Reach upgrades are not necessary in creative."); if (world.isClientSide) EffortlessBuilding.log(player, "Still want increased reach? Use the config."); - return new InteractionResultHolder<>(InteractionResult.PASS, player.getItemInHand(hand)); + return InteractionResultHolder.pass(player.getItemInHand(hand)); } - int currentLevel = EffortlessBuildingClient.POWER_LEVEL.getPowerLevel(player); + int currentLevel = EffortlessBuildingClient.POWER_LEVEL.getPowerLevel(); if (currentLevel == 0) { - EffortlessBuildingClient.POWER_LEVEL.setPowerLevel(player, 1); + EffortlessBuildingClient.POWER_LEVEL.loadPowerLevel(1); if (world.isClientSide) EffortlessBuilding.log(player, "Upgraded reach to " + EffortlessBuildingClient.POWER_LEVEL.getMaxReach(player)); player.setItemInHand(hand, ItemStack.EMPTY); @@ -56,7 +55,7 @@ public class ReachUpgrade1Item extends Item { SoundEvent soundEvent = new SoundEvent(new ResourceLocation("item.armor.equip_leather")); player.playSound(soundEvent, 1f, 1f); } - return new InteractionResultHolder<>(InteractionResult.PASS, player.getItemInHand(hand)); + return InteractionResultHolder.consume(player.getItemInHand(hand)); } @Override diff --git a/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade2Item.java b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade2Item.java index b9ed5ee..27a458e 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade2Item.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade2Item.java @@ -39,9 +39,9 @@ public class ReachUpgrade2Item extends Item { return new InteractionResultHolder<>(InteractionResult.PASS, player.getItemInHand(hand)); } - int currentLevel = EffortlessBuildingClient.POWER_LEVEL.getPowerLevel(player); + int currentLevel = EffortlessBuildingClient.POWER_LEVEL.getPowerLevel(); if (currentLevel == 1) { - EffortlessBuildingClient.POWER_LEVEL.setPowerLevel(player, 2); + EffortlessBuildingClient.POWER_LEVEL.loadPowerLevel(2); if (world.isClientSide) EffortlessBuilding.log(player, "Upgraded reach to " + EffortlessBuildingClient.POWER_LEVEL.getMaxReach(player)); player.setItemInHand(hand, ItemStack.EMPTY); diff --git a/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade3Item.java b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade3Item.java index e0c7873..0c2243d 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade3Item.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade3Item.java @@ -39,9 +39,9 @@ public class ReachUpgrade3Item extends Item { return new InteractionResultHolder<>(InteractionResult.PASS, player.getItemInHand(hand)); } - int currentLevel = EffortlessBuildingClient.POWER_LEVEL.getPowerLevel(player); + int currentLevel = EffortlessBuildingClient.POWER_LEVEL.getPowerLevel(); if (currentLevel == 2) { - EffortlessBuildingClient.POWER_LEVEL.setPowerLevel(player, 3); + EffortlessBuildingClient.POWER_LEVEL.loadPowerLevel(3); if (world.isClientSide) EffortlessBuilding.log(player, "Upgraded reach to " + EffortlessBuildingClient.POWER_LEVEL.getMaxReach(player)); player.setItemInHand(hand, ItemStack.EMPTY); diff --git a/src/main/java/nl/requios/effortlessbuilding/item/SingleItemLootModifier.java b/src/main/java/nl/requios/effortlessbuilding/item/SingleItemLootModifier.java new file mode 100644 index 0000000..684998d --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/item/SingleItemLootModifier.java @@ -0,0 +1,59 @@ +package nl.requios.effortlessbuilding.item; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import net.minecraftforge.common.loot.IGlobalLootModifier; +import net.minecraftforge.common.loot.LootModifier; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; +import nl.requios.effortlessbuilding.EffortlessBuilding; +import org.jetbrains.annotations.NotNull; + +//Adds a single item with a chance to any loot tables. Specify loot tables in the JSON file. +//Add JSON files to resources/data/effortlessbuilding/loot_modifiers, and list them in resources/data/forge/loot_modifiers/global_loot_modifiers.json +//https://forge.gemwire.uk/wiki/Dynamic_Loot_Modification +//https://forums.minecraftforge.net/topic/112960-1182-solved-adding-modded-items-to-existing-vanilla-loot-tables/ +//https://mcreator.net/wiki/minecraft-vanilla-loot-tables-list#toc-index-1 +public class SingleItemLootModifier extends LootModifier { + + public static final RegistryObject> CODEC = EffortlessBuilding.LOOT_MODIFIERS.register("single_item_loot_modifier", () -> + RecordCodecBuilder.create(inst -> codecStart(inst).and( + inst.group( + Codec.FLOAT.fieldOf("chance").forGetter(m -> m.chance), + ForgeRegistries.ITEMS.getCodec().fieldOf("item").forGetter(m -> m.item) + )).apply(inst, SingleItemLootModifier::new) + )); + + private final float chance; + private final Item item; + + public SingleItemLootModifier(LootItemCondition[] conditionsIn, float chance, Item item) { + super(conditionsIn); + this.chance = chance; + this.item = item; + } + + @NotNull + @Override + public ObjectArrayList doApply(ObjectArrayList generatedLoot, LootContext context) { + // + // Additional conditions can be checked, though as much as possible should be parameterized via JSON data. + // It is better to write a new ILootCondition implementation than to do things here. + // + //with chance, add an item + if (context.getRandom().nextFloat() < chance) { + generatedLoot.add(new ItemStack(item, 1)); + } + return generatedLoot; + } + + @Override + public Codec codec() { + return CODEC.get(); + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/network/ModifierSettingsPacket.java b/src/main/java/nl/requios/effortlessbuilding/network/ModifierSettingsPacket.java index ce9199d..f461db0 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/ModifierSettingsPacket.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/ModifierSettingsPacket.java @@ -49,12 +49,12 @@ public class ModifierSettingsPacket { if (ctx.get().getDirection().getReceptionSide().isServer()) { ctx.get().enqueueWork(() -> { var player = ctx.get().getSender(); - //Save to persistent player data + //To server, save to persistent player data player.getPersistentData().put(DATA_KEY, message.modifiersTag); }); } else { ctx.get().enqueueWork(() -> { - //Load from persistent player data + //To client, load into system EffortlessBuildingClient.BUILD_MODIFIERS.deserializeNBT(message.modifiersTag); }); } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/PacketHandler.java b/src/main/java/nl/requios/effortlessbuilding/network/PacketHandler.java index 0baf693..28118ab 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/PacketHandler.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/PacketHandler.java @@ -34,6 +34,8 @@ public class PacketHandler { PerformRedoPacket.Handler::handle, Optional.of(NetworkDirection.PLAY_TO_SERVER)); INSTANCE.registerMessage(id++, ModifierSettingsPacket.class, ModifierSettingsPacket::encode, ModifierSettingsPacket::decode, ModifierSettingsPacket.Handler::handle); + INSTANCE.registerMessage(id++, PowerLevelPacket.class, PowerLevelPacket::encode, PowerLevelPacket::decode, + PowerLevelPacket.Handler::handle); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/PowerLevelPacket.java b/src/main/java/nl/requios/effortlessbuilding/network/PowerLevelPacket.java new file mode 100644 index 0000000..2ddc4b2 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/network/PowerLevelPacket.java @@ -0,0 +1,49 @@ +package nl.requios.effortlessbuilding.network; + +import net.minecraft.network.FriendlyByteBuf; +import net.minecraftforge.network.NetworkEvent; +import nl.requios.effortlessbuilding.EffortlessBuilding; +import nl.requios.effortlessbuilding.EffortlessBuildingClient; + +import java.util.function.Supplier; + +/** + * Sync power level between server and client, for saving and loading. + */ +public class PowerLevelPacket { + + private int powerLevel; + + public PowerLevelPacket() { + } + + public PowerLevelPacket(int powerLevel) { + this.powerLevel = powerLevel; + } + + public static void encode(PowerLevelPacket message, FriendlyByteBuf buf) { + buf.writeInt(message.powerLevel); + } + + public static PowerLevelPacket decode(FriendlyByteBuf buf) { + return new PowerLevelPacket(buf.readInt()); + } + + public static class Handler { + public static void handle(PowerLevelPacket message, Supplier ctx) { + if (ctx.get().getDirection().getReceptionSide().isServer()) { + ctx.get().enqueueWork(() -> { + var player = ctx.get().getSender(); + //To server, save to persistent player data + EffortlessBuilding.SERVER_POWER_LEVEL.setPowerLevel(player, message.powerLevel); + }); + } else { + ctx.get().enqueueWork(() -> { + //To client, load into system + EffortlessBuildingClient.POWER_LEVEL.setPowerLevel(message.powerLevel); + }); + } + ctx.get().setPacketHandled(true); + } + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/systems/BuildSettings.java b/src/main/java/nl/requios/effortlessbuilding/systems/BuildSettings.java index 1b5aa7c..e1c14fd 100644 --- a/src/main/java/nl/requios/effortlessbuilding/systems/BuildSettings.java +++ b/src/main/java/nl/requios/effortlessbuilding/systems/BuildSettings.java @@ -68,6 +68,6 @@ public class BuildSettings { } private boolean canReplaceBlocks(){ - return Minecraft.getInstance().player != null && PowerLevel.canReplaceBlocks(Minecraft.getInstance().player); + return Minecraft.getInstance().player != null && EffortlessBuildingClient.POWER_LEVEL.canReplaceBlocks(Minecraft.getInstance().player); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/systems/BuilderChain.java b/src/main/java/nl/requios/effortlessbuilding/systems/BuilderChain.java index debac48..d542c76 100644 --- a/src/main/java/nl/requios/effortlessbuilding/systems/BuilderChain.java +++ b/src/main/java/nl/requios/effortlessbuilding/systems/BuilderChain.java @@ -103,7 +103,7 @@ public class BuilderChain { } var player = Minecraft.getInstance().player; - if (player != null && !PowerLevel.canBreakFar(player)) return; + if (player != null && !EffortlessBuildingClient.POWER_LEVEL.canBreakFar(player)) return; if (buildingState == BuildingState.IDLE){ buildingState = BuildingState.BREAKING; @@ -220,7 +220,7 @@ public class BuilderChain { var startPos = lookingAt.getBlockPos(); //Check if out of reach - int maxReach = EffortlessBuildingClient.POWER_LEVEL.getMaxReach(player); + int maxReach = EffortlessBuildingClient.POWER_LEVEL.getPlacementReach(player); if (player.blockPosition().distSqr(startPos) > maxReach * maxReach) return null; startPosForBreaking = startPos; @@ -240,7 +240,7 @@ public class BuilderChain { //We can only break //Do not break far if we are not allowed to - if (!shouldLookAtNear && !PowerLevel.canBreakFar(player)) return null; + if (!shouldLookAtNear && !EffortlessBuildingClient.POWER_LEVEL.canBreakFar(player)) return null; } var blockEntry = new BlockEntry(startPos); diff --git a/src/main/java/nl/requios/effortlessbuilding/systems/PowerLevel.java b/src/main/java/nl/requios/effortlessbuilding/systems/PowerLevel.java index f5477c3..0efbb4f 100644 --- a/src/main/java/nl/requios/effortlessbuilding/systems/PowerLevel.java +++ b/src/main/java/nl/requios/effortlessbuilding/systems/PowerLevel.java @@ -1,49 +1,46 @@ package nl.requios.effortlessbuilding.systems; import net.minecraft.world.entity.player.Player; -import net.minecraft.util.Mth; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import nl.requios.effortlessbuilding.CommonConfig; -import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuildingClient; +import nl.requios.effortlessbuilding.network.PacketHandler; +import nl.requios.effortlessbuilding.network.PowerLevelPacket; -//Common +@OnlyIn(Dist.CLIENT) public class PowerLevel { - private static final String POWER_LEVEL_KEY = EffortlessBuilding.MODID + ":powerLevel"; private static final int MAX_POWER_LEVEL = 3; + private int powerLevel; - public int getPowerLevel(Player player) { - if (!player.getPersistentData().contains(POWER_LEVEL_KEY)) return 0; - return player.getPersistentData().getInt(POWER_LEVEL_KEY); + public int getPowerLevel() { + return powerLevel; } - public void increasePowerLevel(Player player) { - int powerLevel = getPowerLevel(player); - if (powerLevel < MAX_POWER_LEVEL) { - setPowerLevel(player, powerLevel + 1); - } - } - - public void setPowerLevel(Player player, int powerLevel) { - player.getPersistentData().putInt(POWER_LEVEL_KEY, powerLevel); - - if (player.level.isClientSide) { - EffortlessBuildingClient.BUILD_MODIFIERS.onPowerLevelChanged(powerLevel); + public void setPowerLevel(int powerLevel) { + this.powerLevel = powerLevel; + EffortlessBuildingClient.BUILD_MODIFIERS.onPowerLevelChanged(powerLevel); + } + + public boolean canIncreasePowerLevel() { + return getPowerLevel() < MAX_POWER_LEVEL; + } + + public void increasePowerLevel() { + if (canIncreasePowerLevel()) { + setPowerLevel(getPowerLevel() + 1); + PacketHandler.INSTANCE.sendToServer(new PowerLevelPacket(powerLevel)); } } + @Deprecated public int getMaxReach(Player player) { - if (player.isCreative()) return CommonConfig.reach.creative.get(); - return switch (getPowerLevel(player)) { - case 1 -> CommonConfig.reach.level1.get(); - case 2 -> CommonConfig.reach.level2.get(); - case 3 -> CommonConfig.reach.level3.get(); - default -> CommonConfig.reach.level0.get(); - }; + return getPlacementReach(player); } public int getPlacementReach(Player player) { if (player.isCreative()) return CommonConfig.reach.creative.get(); - return switch (getPowerLevel(player)) { + return switch (getPowerLevel()) { case 1 -> CommonConfig.reach.level1.get(); case 2 -> CommonConfig.reach.level2.get(); case 3 -> CommonConfig.reach.level3.get(); @@ -54,12 +51,12 @@ public class PowerLevel { //How far away we can detect the second and third click of build modes (distance to player) public int getBuildModeReach(Player player) { //A bit further than placement reach, so you can build lines when looking to the side without having to move. - return getMaxReach(player) + 6; + return getPlacementReach(player) + 6; } public int getMaxBlocksPlacedAtOnce(Player player) { if (player.isCreative()) return CommonConfig.maxBlocksPlacedAtOnce.creative.get(); - return switch (getPowerLevel(player)) { + return switch (getPowerLevel()) { case 1 -> CommonConfig.maxBlocksPlacedAtOnce.level1.get(); case 2 -> CommonConfig.maxBlocksPlacedAtOnce.level2.get(); case 3 -> CommonConfig.maxBlocksPlacedAtOnce.level3.get(); @@ -69,7 +66,7 @@ public class PowerLevel { public int getMaxBlocksPerAxis(Player player) { if (player.isCreative()) return CommonConfig.maxBlocksPerAxis.creative.get(); - return switch (getPowerLevel(player)) { + return switch (getPowerLevel()) { case 1 -> CommonConfig.maxBlocksPerAxis.level1.get(); case 2 -> CommonConfig.maxBlocksPerAxis.level2.get(); case 3 -> CommonConfig.maxBlocksPerAxis.level3.get(); @@ -79,7 +76,7 @@ public class PowerLevel { public int getMaxMirrorRadius(Player player) { if (player.isCreative()) return CommonConfig.maxMirrorRadius.creative.get(); - return switch (getPowerLevel(player)) { + return switch (getPowerLevel()) { case 1 -> CommonConfig.maxMirrorRadius.level1.get(); case 2 -> CommonConfig.maxMirrorRadius.level2.get(); case 3 -> CommonConfig.maxMirrorRadius.level3.get(); @@ -91,12 +88,11 @@ public class PowerLevel { return getMaxBlocksPlacedAtOnce(player) <= 0 || getMaxBlocksPerAxis(player) <= 0; } - //Static methods are used by client and server - public static boolean canBreakFar(Player player) { + public boolean canBreakFar(Player player) { return player.isCreative(); } - public static boolean canReplaceBlocks(Player player) { + public boolean canReplaceBlocks(Player player) { return player.isCreative(); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/systems/ServerBuildState.java b/src/main/java/nl/requios/effortlessbuilding/systems/ServerBuildState.java index fd71db2..6206dfb 100644 --- a/src/main/java/nl/requios/effortlessbuilding/systems/ServerBuildState.java +++ b/src/main/java/nl/requios/effortlessbuilding/systems/ServerBuildState.java @@ -2,6 +2,7 @@ package nl.requios.effortlessbuilding.systems; import net.minecraft.world.entity.player.Player; import nl.requios.effortlessbuilding.EffortlessBuilding; +import nl.requios.effortlessbuilding.EffortlessBuildingClient; public class ServerBuildState { private static final String IS_USING_BUILD_MODE_KEY = EffortlessBuilding.MODID + ":isUsingBuildMode"; @@ -25,7 +26,7 @@ public class ServerBuildState { } public static boolean isQuickReplacing(Player player) { - if (!PowerLevel.canReplaceBlocks(player)) return false; + if (!EffortlessBuilding.SERVER_POWER_LEVEL.canReplaceBlocks(player)) return false; return player.getPersistentData().contains(IS_QUICK_REPLACING_KEY); } diff --git a/src/main/java/nl/requios/effortlessbuilding/systems/ServerPowerLevel.java b/src/main/java/nl/requios/effortlessbuilding/systems/ServerPowerLevel.java new file mode 100644 index 0000000..1a07a15 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/systems/ServerPowerLevel.java @@ -0,0 +1,33 @@ +package nl.requios.effortlessbuilding.systems; + +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.player.Player; +import net.minecraftforge.network.PacketDistributor; +import nl.requios.effortlessbuilding.EffortlessBuilding; +import nl.requios.effortlessbuilding.network.PacketHandler; +import nl.requios.effortlessbuilding.network.PowerLevelPacket; + +public class ServerPowerLevel { + private static final String POWER_LEVEL_KEY = EffortlessBuilding.MODID + ":powerLevel"; + + public int getPowerLevel(Player player) { + if (!player.getPersistentData().contains(POWER_LEVEL_KEY)) return 0; + return player.getPersistentData().getInt(POWER_LEVEL_KEY); + } + + public void setPowerLevel(Player player, int powerLevel) { + player.getPersistentData().putInt(POWER_LEVEL_KEY, powerLevel); + } + + public void sendToClient(Player player) { + PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new PowerLevelPacket(getPowerLevel(player))); + } + + public boolean canBreakFar(Player player) { + return player.isCreative(); + } + + public boolean canReplaceBlocks(Player player) { + return player.isCreative(); + } +} diff --git a/src/main/resources/assets/effortlessbuilding/lang/en_us.json b/src/main/resources/assets/effortlessbuilding/lang/en_us.json index 9f34dc2..e65e284 100644 --- a/src/main/resources/assets/effortlessbuilding/lang/en_us.json +++ b/src/main/resources/assets/effortlessbuilding/lang/en_us.json @@ -12,6 +12,7 @@ "key.effortlessbuilding.altplacement.desc": "Alternative placement", "key.effortlessbuilding.previous_build_mode.desc": "Activate Previous Build Mode", "key.effortlessbuilding.disable_build_mode_toggle.desc": "Toggle Disabled <> Previous Build Mode", + "key.effortlessbuilding.upgrade_power_level": "Use to permanently upgrade your Building Power Level by 1.", "item.effortlessbuilding.randomizer_bag": "Leather Randomizer Bag", "item.effortlessbuilding.golden_randomizer_bag": "Golden Randomizer Bag", @@ -19,6 +20,12 @@ "item.effortlessbuilding.reach_upgrade1": "Reach Upgrade 1", "item.effortlessbuilding.reach_upgrade2": "Reach Upgrade 2", "item.effortlessbuilding.reach_upgrade3": "Reach Upgrade 3", + "item.effortlessbuilding.muscles": "Muscles", + "item.effortlessbuilding.muscles.desc": "Train your biceps to place multiple blocks at once.", + "item.effortlessbuilding.elastic_hand": "Elastic Hand", + "item.effortlessbuilding.elastic_hand.desc": "A flexible arm to place blocks further away.", + "item.effortlessbuilding.building_techniques_book": "Building Techniques Book", + "item.effortlessbuilding.building_techniques_book.desc": "Contains various building techniques to help you build faster.", "effortlessbuilding.mode.normal": "Disable", "effortlessbuilding.mode.normal_plus": "Single", @@ -98,5 +105,6 @@ "effortlessbuilding.tooltip.holdForControls": "Hold [%1$s] for Controls", "effortlessbuilding.tooltip.keyShift": "Shift", "effortlessbuilding.tooltip.keyCtrl": "Ctrl", - "effortlessbuilding.tooltip.keybind": "[%1$s]" + "effortlessbuilding.tooltip.keybind": "[%1$s]", + "fdsaf": "key.effortlessbuilding.upgrade_power_level" } diff --git a/src/main/resources/assets/effortlessbuilding/models/item/building_techniques_book.json b/src/main/resources/assets/effortlessbuilding/models/item/building_techniques_book.json new file mode 100644 index 0000000..c7d4c0c --- /dev/null +++ b/src/main/resources/assets/effortlessbuilding/models/item/building_techniques_book.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "effortlessbuilding:items/buildingtechniquesbook" + } +} diff --git a/src/main/resources/assets/effortlessbuilding/models/item/elastic_hand.json b/src/main/resources/assets/effortlessbuilding/models/item/elastic_hand.json new file mode 100644 index 0000000..4fcb467 --- /dev/null +++ b/src/main/resources/assets/effortlessbuilding/models/item/elastic_hand.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "effortlessbuilding:items/elastichand" + } +} diff --git a/src/main/resources/assets/effortlessbuilding/models/item/muscles.json b/src/main/resources/assets/effortlessbuilding/models/item/muscles.json new file mode 100644 index 0000000..c44e1d6 --- /dev/null +++ b/src/main/resources/assets/effortlessbuilding/models/item/muscles.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "effortlessbuilding:items/muscles" + } +} diff --git a/src/main/resources/assets/effortlessbuilding/textures/items/muscles.png b/src/main/resources/assets/effortlessbuilding/textures/items/muscles.png index 2ea9a5f..0b3f104 100644 Binary files a/src/main/resources/assets/effortlessbuilding/textures/items/muscles.png and b/src/main/resources/assets/effortlessbuilding/textures/items/muscles.png differ diff --git a/src/main/resources/data/effortlessbuilding/loot_modifiers/building_techniques_book_library_loot_modifier.json b/src/main/resources/data/effortlessbuilding/loot_modifiers/building_techniques_book_library_loot_modifier.json new file mode 100644 index 0000000..692cadc --- /dev/null +++ b/src/main/resources/data/effortlessbuilding/loot_modifiers/building_techniques_book_library_loot_modifier.json @@ -0,0 +1,11 @@ +{ + "type": "effortlessbuilding:single_item_loot_modifier", + "conditions": [ + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/stronghold_library" + } + ], + "item": "effortlessbuilding:building_techniques_book", + "chance": 0.6 +} \ No newline at end of file diff --git a/src/main/resources/data/effortlessbuilding/loot_modifiers/building_techniques_book_loot_modifier.json b/src/main/resources/data/effortlessbuilding/loot_modifiers/building_techniques_book_loot_modifier.json new file mode 100644 index 0000000..0787e1d --- /dev/null +++ b/src/main/resources/data/effortlessbuilding/loot_modifiers/building_techniques_book_loot_modifier.json @@ -0,0 +1,92 @@ +{ + "type": "effortlessbuilding:single_item_loot_modifier", + "conditions": [ + { + "condition": "minecraft:alternative", + "terms": [ + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/abandoned_mineshaft" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/ancient_city" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/bastion_bridge" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/bastion_other" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/bastion_treasure" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/buried_treasure" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/desert_pyramid" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/end_city_treasure" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/igloo_chest" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/jungle_temple" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/nether_bridge" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/pillager_outpost" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/ruined_portal" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/shipwreck_supply" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/shipwreck_treasure" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/simple_dungeon" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/stronghold_corridor" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/stronghold_crossing" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/stronghold_library" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/woodland_mansion" + } + ] + } + ], + "item": "effortlessbuilding:building_techniques_book", + "chance": 0.05 +} \ No newline at end of file diff --git a/src/main/resources/data/effortlessbuilding/loot_modifiers/elastic_hand_loot_modifier.json b/src/main/resources/data/effortlessbuilding/loot_modifiers/elastic_hand_loot_modifier.json new file mode 100644 index 0000000..a93e016 --- /dev/null +++ b/src/main/resources/data/effortlessbuilding/loot_modifiers/elastic_hand_loot_modifier.json @@ -0,0 +1,92 @@ +{ + "type": "effortlessbuilding:single_item_loot_modifier", + "conditions": [ + { + "condition": "minecraft:alternative", + "terms": [ + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/abandoned_mineshaft" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/ancient_city" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/bastion_bridge" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/bastion_other" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/bastion_treasure" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/buried_treasure" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/desert_pyramid" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/end_city_treasure" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/igloo_chest" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/jungle_temple" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/nether_bridge" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/pillager_outpost" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/ruined_portal" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/shipwreck_supply" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/shipwreck_treasure" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/simple_dungeon" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/stronghold_corridor" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/stronghold_crossing" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/stronghold_library" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/woodland_mansion" + } + ] + } + ], + "item": "effortlessbuilding:elastic_hand", + "chance": 0.07 +} \ No newline at end of file diff --git a/src/main/resources/data/effortlessbuilding/loot_modifiers/muscles_loot_modifier.json b/src/main/resources/data/effortlessbuilding/loot_modifiers/muscles_loot_modifier.json new file mode 100644 index 0000000..e209bb2 --- /dev/null +++ b/src/main/resources/data/effortlessbuilding/loot_modifiers/muscles_loot_modifier.json @@ -0,0 +1,92 @@ +{ + "type": "effortlessbuilding:single_item_loot_modifier", + "conditions": [ + { + "condition": "minecraft:alternative", + "terms": [ + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/abandoned_mineshaft" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/ancient_city" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/bastion_bridge" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/bastion_other" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/bastion_treasure" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/buried_treasure" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/desert_pyramid" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/end_city_treasure" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/igloo_chest" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/jungle_temple" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/nether_bridge" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/pillager_outpost" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/ruined_portal" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/shipwreck_supply" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/shipwreck_treasure" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/simple_dungeon" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/stronghold_corridor" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/stronghold_crossing" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/stronghold_library" + }, + { + "condition": "forge:loot_table_id", + "loot_table_id": "minecraft:chests/woodland_mansion" + } + ] + } + ], + "item": "effortlessbuilding:muscles", + "chance": 0.07 +} \ No newline at end of file diff --git a/src/main/resources/data/forge/loot_modifiers/global_loot_modifiers.json b/src/main/resources/data/forge/loot_modifiers/global_loot_modifiers.json new file mode 100644 index 0000000..853a8b9 --- /dev/null +++ b/src/main/resources/data/forge/loot_modifiers/global_loot_modifiers.json @@ -0,0 +1,9 @@ +{ + "replace": false, + "entries": [ + "effortlessbuilding:muscles_loot_modifier", + "effortlessbuilding:elastic_hand_loot_modifier", + "effortlessbuilding:building_techniques_book_loot_modifier", + "effortlessbuilding:building_techniques_book_library_loot_modifier" + ] +} \ No newline at end of file