diff --git a/README.md b/README.md index 09ce67e..b6b31e9 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ It's also compatible with **any** modded crops, to ease your mind of one more th ***If you're using the 9.0.0.0-beta version, be aware that the mod ID changed from `harvestwithease` to `harvest_with_ease`.*** ***Backup your configuration file and update the new one at the first run with the beta version.*** ***Furthermore, Harvest with ease now requires Cobweb API to work, so install that too!*** -***For any problem that might arise, do not hesitate to open an issue on GitHub!*** +***For any problem that might arise, do not hesitate to open an issue on GitHub or contact us directly on our Discord!*** ## **Features** diff --git a/common/build.gradle b/common/build.gradle index f5e6134..78dbda2 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -11,6 +11,6 @@ minecraft { dependencies { compileOnly group: "org.spongepowered", name: "mixin", version: "0.8.5" - compileOnly "it.crystalnest:cobweb-common:${minecraft_version}-${cobweb_version}" - compileOnly "fuzs.forgeconfigapiport:forgeconfigapiport-common-neoforgeapi:${fcap_version}" + implementation "it.crystalnest:cobweb-common:${minecraft_version}-${cobweb_version}" + implementation "fuzs.forgeconfigapiport:forgeconfigapiport-common-neoforgeapi:${fcap_version}" } diff --git a/common/src/main/java/it/crystalnest/harvest_with_ease/api/HarvestUtils.java b/common/src/main/java/it/crystalnest/harvest_with_ease/api/HarvestUtils.java index 8fa5c99..17d3181 100644 --- a/common/src/main/java/it/crystalnest/harvest_with_ease/api/HarvestUtils.java +++ b/common/src/main/java/it/crystalnest/harvest_with_ease/api/HarvestUtils.java @@ -6,7 +6,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.tags.BlockTags; import net.minecraft.world.item.TieredItem; -import net.minecraft.world.level.Level; +import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.CocoaBlock; import net.minecraft.world.level.block.CropBlock; @@ -44,7 +44,7 @@ public static boolean isCrop(Block block) { * @throws ClassCastException if the age property is not an {@link IntegerProperty}. */ public static IntegerProperty getAge(BlockState blockState) throws NullPointerException, NoSuchElementException, ClassCastException { - return (IntegerProperty) blockState.getProperties().stream().filter(property -> property.getName().equals("age")).findFirst().orElseThrow(); + return (IntegerProperty) blockState.getProperties().stream().filter(property -> "age".equals(property.getName())).findFirst().orElseThrow(); } /** @@ -74,12 +74,12 @@ public static boolean isMature(BlockState blockState) throws NullPointerExceptio /** * Checks whether the given crop is a multi-block crop (a crop made of multiple vertically connected blocks). * - * @param level {@link Level world} in which the crop is placed. + * @param level {@link BlockGetter world} in which the crop is placed. * @param blockState {@link BlockState} of the crop. * @param blockPos {@link BlockPos} of the crop. * @return whether the given crop is a multi-block crop. */ - public static boolean isTallCrop(Level level, BlockState blockState, BlockPos blockPos) { + public static boolean isTallCrop(BlockGetter level, BlockState blockState, BlockPos blockPos) { return blockState.is(BlockTags.CROPS) && level.getBlockState(blockPos.below()).is(blockState.getBlock()) || level.getBlockState(blockPos.above()).is(blockState.getBlock()); } diff --git a/common/src/main/java/it/crystalnest/harvest_with_ease/api/event/HarvestEvent.java b/common/src/main/java/it/crystalnest/harvest_with_ease/api/event/HarvestEvent.java index b3fe7c9..7af8fb2 100644 --- a/common/src/main/java/it/crystalnest/harvest_with_ease/api/event/HarvestEvent.java +++ b/common/src/main/java/it/crystalnest/harvest_with_ease/api/event/HarvestEvent.java @@ -147,7 +147,8 @@ interface HarvestDropsEvent extends HarvestEvent { * @return whether the list of drops changed from its default value. */ default boolean didDropsChange() { - List defaultDrops = getDefaultDrops(), drops = getDrops(); + List defaultDrops = getDefaultDrops(); + List drops = getDrops(); if (defaultDrops.size() == drops.size()) { for (int c = 0; c < defaultDrops.size(); c++) { if (!ItemStack.matches(defaultDrops.get(c), drops.get(c))) { diff --git a/common/src/main/java/it/crystalnest/harvest_with_ease/config/ModConfig.java b/common/src/main/java/it/crystalnest/harvest_with_ease/config/ModConfig.java index cd57cda..f6e69a7 100644 --- a/common/src/main/java/it/crystalnest/harvest_with_ease/config/ModConfig.java +++ b/common/src/main/java/it/crystalnest/harvest_with_ease/config/ModConfig.java @@ -131,30 +131,12 @@ public static AreaStep getAreaIncrementStep() { return CONFIG.areaIncrementStep.get(); } - @Override - protected void define(ModConfigSpec.Builder builder) { - crops = builder.comment(" List of in-game IDs of additional crops").defineListAllowEmpty(List.of("crops"), Collections::emptyList, this::stringListValidator); - requireHoe = builder.comment(" Require holding a hoe (either hands) to right-click harvest").define("require hoe", false); - damageOnHarvest = builder.comment(" If [require hoe] is set to true, damage the hoe of the given amount (0 to disable, must be an integer)").defineInRange("damage on harvest", 0, 0, Integer.MAX_VALUE); - grantedExp = builder.comment(" Amount of experience to grant on harvest (0 to disable, must be an integer).").defineInRange("exp on harvest", 0, 0, Integer.MAX_VALUE); - multiHarvestStartingTier = builder.comment( - " Tool tier starting from which it is possible to harvest multiple crops at once.", - " All tiers that cannot multi-harvest will have a 1x1 square area of effect (a single crop).", - " If [starting harvest area size] is set to \"" + AreaSize.SINGLE + "\" and [area increment step] to \"" + AreaStep.NONE + "\" multi-harvest will be effectively disabled, regardless of this config option value.", - " From lesser to greater, Vanilla tiers are: " + String.join(", ", Stream.of(Tiers.values()).sorted(TierUtils::compare).map(tier -> "\"" + tier.toString().toLowerCase() + "\"").toArray(String[]::new)) + ".", - " When set to \"none\", multi-harvest will be enabled without a tool too. Note that [require hoe] takes precedence.", - " The tier can be specified with either the name of the tier, e.g. \"iron\", or the id of the tier, e.g. \"minecraft:iron\"." - ).define("multi-harvest starting tier", Tiers.WOOD.toString().toLowerCase(), value -> value instanceof String string && (string.equalsIgnoreCase("none") || TierUtils.isIn(TierUtils.getAllTiers(), string))); - areaStartingSize = builder.comment(getAreaSizeComments()).defineEnum("starting harvest area size", AreaSize.SINGLE, AreaSize.values()); - areaIncrementStep = builder.comment(getAreaStepComments()).defineEnum("area increment step", AreaStep.NONE, AreaStep.values()); - } - /** * Gets the comments for {@link #areaStartingSize}. * * @return the comments for {@link #areaStartingSize}. */ - private String[] getAreaSizeComments() { + private static String[] getAreaSizeComments() { AreaSize[] sizes = AreaSize.values(); String[] comments = new String[3 + sizes.length]; comments[0] = " Starting multi-harvest area size (square side length)."; @@ -171,15 +153,34 @@ private String[] getAreaSizeComments() { * * @return the comments for {@link #areaIncrementStep}. */ - private String[] getAreaStepComments() { + private static String[] getAreaStepComments() { AreaStep[] steps = AreaStep.values(); String[] comments = new String[2 + steps.length]; comments[0] = " Increment step for the harvest area size with higher tool tiers."; comments[1] = " Setting this to \"" + AreaStep.NONE + "\" and [starting harvest area size] to \"" + AreaSize.SINGLE + "\" will effectively disable multi-harvest."; comments[2] = " \"" + steps[0] + "\" - no increment, the area stays the same (as defined by [starting harvest area size]) regardless of the tool used, if any."; for (int i = 1; i < steps.length; i++) { - comments[i + 2] = " \"" + steps[i] + "\" - " + steps[i] + " increment, the size of the area, starting from [starting harvest area size], increases by " + steps[i].step + " with each higher tier. E.g. 1x1 -> " + (1 + steps[i].step) + "x" + (1 + steps[i].step) + " -> " + (1 + steps[i].step * 2) + "x" + (1 + steps[i].step * 2) + " -> ..."; + comments[i + 2] = " \"" + steps[i] + "\" - " + steps[i] + " increment, the size of the area, starting from [starting harvest area size], increases by " + steps[i].step + " with each higher tier." + + "E.g. 1x1 -> " + (1 + steps[i].step) + "x" + (1 + steps[i].step) + " -> " + (1 + steps[i].step * 2) + "x" + (1 + steps[i].step * 2) + " -> ..."; } return comments; } + + @Override + protected void define(ModConfigSpec.Builder builder) { + crops = builder.comment(" List of in-game IDs of additional crops").defineListAllowEmpty(List.of("crops"), Collections::emptyList, this::stringListValidator); + requireHoe = builder.comment(" Require holding a hoe (either hands) to right-click harvest").define("require hoe", false); + damageOnHarvest = builder.comment(" If [require hoe] is set to true, damage the hoe of the given amount (0 to disable, must be an integer)").defineInRange("damage on harvest", 0, 0, Integer.MAX_VALUE); + grantedExp = builder.comment(" Amount of experience to grant on harvest (0 to disable, must be an integer).").defineInRange("exp on harvest", 0, 0, Integer.MAX_VALUE); + multiHarvestStartingTier = builder.comment( + " Tool tier starting from which it is possible to harvest multiple crops at once.", + " All tiers that cannot multi-harvest will have a 1x1 square area of effect (a single crop).", + " If [starting harvest area size] is set to \"" + AreaSize.SINGLE + "\" and [area increment step] to \"" + AreaStep.NONE + "\" multi-harvest will be effectively disabled, regardless of this config option value.", + " From lesser to greater, Vanilla tiers are: " + String.join(", ", Stream.of(Tiers.values()).sorted(TierUtils::compare).map(tier -> "\"" + tier.toString().toLowerCase() + "\"").toArray(String[]::new)) + ".", + " When set to \"none\", multi-harvest will be enabled without a tool too. Note that [require hoe] takes precedence.", + " The tier can be specified with either the name of the tier, e.g. \"iron\", or the id of the tier, e.g. \"minecraft:iron\"." + ).define("multi-harvest starting tier", Tiers.WOOD.toString().toLowerCase(), value -> value instanceof String string && ("none".equalsIgnoreCase(string) || TierUtils.isIn(TierUtils.getAllTiers(), string))); + areaStartingSize = builder.comment(getAreaSizeComments()).defineEnum("starting harvest area size", AreaSize.SINGLE, AreaSize.values()); + areaIncrementStep = builder.comment(getAreaStepComments()).defineEnum("area increment step", AreaStep.NONE, AreaStep.values()); + } } diff --git a/common/src/main/java/it/crystalnest/harvest_with_ease/handler/HarvestHandler.java b/common/src/main/java/it/crystalnest/harvest_with_ease/handler/HarvestHandler.java index 6ba9801..fb3d11a 100644 --- a/common/src/main/java/it/crystalnest/harvest_with_ease/handler/HarvestHandler.java +++ b/common/src/main/java/it/crystalnest/harvest_with_ease/handler/HarvestHandler.java @@ -38,6 +38,11 @@ * Handler for harvest related events. */ public abstract class HarvestHandler { + /** + * + */ + protected HarvestHandler() {} + /** * Handles block breaking harvest (left-click harvest). * @@ -69,7 +74,7 @@ protected static void handle(LevelAccessor level, BlockState crop, BlockPos pos) */ protected static boolean handle(Level level, BlockState crop, Direction face, BlockPos pos, BlockHitResult hitResult, Player player, InteractionHand hand) { boolean consume = false; - if (hand == getValidHand(player) && canHarvest(level, crop, pos, face, hitResult, player, hand)) { + if (hand != null && hand == getValidHand(player) && canHarvest(level, crop, pos, face, hitResult, player, hand)) { try { IntegerProperty age = HarvestUtils.getAge(crop); if (HarvestUtils.isMature(crop, age)) { @@ -273,8 +278,8 @@ protected static boolean isTallButSeparate(Block crop) { * @param pos crop position. */ private static void logError(Exception e, BlockPos pos) { - Constants.LOGGER.debug("Exception generated by block at [" + pos.toShortString() + "]"); - Constants.LOGGER.debug("This is a non blocking error, but can result in incorrect behavior for mod " + Constants.MOD_ID); + Constants.LOGGER.debug("Exception generated by block at [{}]", pos.toShortString()); + Constants.LOGGER.debug("This is a non blocking error, but can result in incorrect behavior for mod {}", Constants.MOD_ID); Constants.LOGGER.debug("Most likely, it wasn't possible to retrieve a crop age property, either for an invalid item in the cropIds configuration option or for a mod incompatibility; see stack trace for more details", e); } } diff --git a/fabric/build.gradle b/fabric/build.gradle index 9e56cd6..7834cfd 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -6,8 +6,8 @@ dependencies { modImplementation "net.fabricmc:fabric-loader:${fabric_loader_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}" compileOnly project(":common") - modCompileOnly "it.crystalnest:cobweb-fabric:${minecraft_version}-${cobweb_version}" - modCompileOnly "fuzs.forgeconfigapiport:forgeconfigapiport-fabric:${fcap_version}" + modImplementation "it.crystalnest:cobweb-fabric:${minecraft_version}-${cobweb_version}" + modImplementation "fuzs.forgeconfigapiport:forgeconfigapiport-fabric:${fcap_version}" } loom { diff --git a/fabric/src/main/java/it/crystalnest/harvest_with_ease/api/event/HarvestEvents.java b/fabric/src/main/java/it/crystalnest/harvest_with_ease/api/event/HarvestEvents.java index f005414..154f822 100644 --- a/fabric/src/main/java/it/crystalnest/harvest_with_ease/api/event/HarvestEvents.java +++ b/fabric/src/main/java/it/crystalnest/harvest_with_ease/api/event/HarvestEvents.java @@ -157,7 +157,7 @@ public interface AfterHarvest { /** * Generic Fabric harvest event. */ - public static abstract class FabricHarvestEvent

implements HarvestEvent { + public abstract static class FabricHarvestEvent

implements HarvestEvent { /** * Level in which the interaction takes place. */ @@ -353,7 +353,7 @@ public void setDrops(List drops) { @Override public void cancel() { - canceled = false; + canceled = true; } } diff --git a/forge/build.gradle b/forge/build.gradle index 1229c23..14f2b10 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -70,8 +70,8 @@ dependencies { minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" compileOnly project(":common") annotationProcessor("org.spongepowered:mixin:0.8.5-SNAPSHOT:processor") - compileOnly "it.crystalnest:cobweb-forge:${minecraft_version}-${cobweb_version}" - compileOnly(fg.deobf("fuzs.forgeconfigapiport:forgeconfigapiport-forge:${fcap_version}")) + implementation "it.crystalnest:cobweb-forge:${minecraft_version}-${cobweb_version}" + implementation(fg.deobf("fuzs.forgeconfigapiport:forgeconfigapiport-forge:${fcap_version}")) } tasks.withType(JavaCompile).configureEach { diff --git a/forge/src/main/java/it/crystalnest/harvest_with_ease/handler/ForgeHarvestHandler.java b/forge/src/main/java/it/crystalnest/harvest_with_ease/handler/ForgeHarvestHandler.java index 120469d..1e7e50b 100644 --- a/forge/src/main/java/it/crystalnest/harvest_with_ease/handler/ForgeHarvestHandler.java +++ b/forge/src/main/java/it/crystalnest/harvest_with_ease/handler/ForgeHarvestHandler.java @@ -35,7 +35,10 @@ private static void handle(BlockEvent.BreakEvent event) { */ @SubscribeEvent(priority = EventPriority.HIGH) private static void handle(PlayerInteractEvent.RightClickBlock event) { - if (canInteract(event.getEntity(), event) && handle(event.getLevel(), event.getLevel().getBlockState(event.getHitVec().getBlockPos()), event.getHitVec().getDirection(), event.getHitVec().getBlockPos(), event.getHitVec(), event.getEntity(), event.getHand())) { + if ( + canInteract(event.getEntity(), event) && + handle(event.getLevel(), event.getLevel().getBlockState(event.getHitVec().getBlockPos()), event.getHitVec().getDirection(), event.getHitVec().getBlockPos(), event.getHitVec(), event.getEntity(), event.getHand()) + ) { event.setCancellationResult(InteractionResult.SUCCESS); event.setCanceled(true); } diff --git a/gradle.properties b/gradle.properties index b5d4cb8..e81a547 100644 --- a/gradle.properties +++ b/gradle.properties @@ -28,7 +28,7 @@ neoforge_version = 20.4.170 neoforge_loader_version_range = [20.4,) # Dependencies -cobweb_version = 0.0.2.4-alpha +cobweb_version = 0.0.2.5-alpha fcap_version = 20.4.3 # Gradle diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 4f13ed9..039c0b8 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -31,7 +31,7 @@ sourceSets.main.resources { srcDir "src/generated/resources" } dependencies { implementation "net.neoforged:neoforge:${neoforge_version}" compileOnly project(":common") - compileOnly "it.crystalnest:cobweb-neoforge:${minecraft_version}-${cobweb_version}" + implementation "it.crystalnest:cobweb-neoforge:${minecraft_version}-${cobweb_version}" } // NeoGradle compiles the game, but we don't want to add our common code to the game's code diff --git a/neoforge/src/main/java/it/crystalnest/harvest_with_ease/ModLoader.java b/neoforge/src/main/java/it/crystalnest/harvest_with_ease/ModLoader.java index 4813904..161cdf6 100644 --- a/neoforge/src/main/java/it/crystalnest/harvest_with_ease/ModLoader.java +++ b/neoforge/src/main/java/it/crystalnest/harvest_with_ease/ModLoader.java @@ -16,4 +16,4 @@ public class ModLoader { public ModLoader(IEventBus bus) { CommonModLoader.init(); } -} \ No newline at end of file +} diff --git a/neoforge/src/main/java/it/crystalnest/harvest_with_ease/api/event/HarvestEvents.java b/neoforge/src/main/java/it/crystalnest/harvest_with_ease/api/event/HarvestEvents.java index afd021a..b3f8990 100644 --- a/neoforge/src/main/java/it/crystalnest/harvest_with_ease/api/event/HarvestEvents.java +++ b/neoforge/src/main/java/it/crystalnest/harvest_with_ease/api/event/HarvestEvents.java @@ -28,7 +28,7 @@ private HarvestEvents() {} /** * Generic Forge harvest event. */ - public static class ForgeHarvestEvent

extends PlayerInteractEvent implements HarvestEvent { + public static class NeoForgeHarvestEvent

extends PlayerInteractEvent implements HarvestEvent { /** * Level in which the interaction takes place. */ @@ -54,7 +54,7 @@ public static class ForgeHarvestEvent

extends * @param player {@link #player}. * @param hand {@link #hand}. */ - protected ForgeHarvestEvent(L level, BlockState crop, BlockPos pos, Direction face, @Nullable BlockHitResult hitResult, P player, InteractionHand hand) { + protected NeoForgeHarvestEvent(L level, BlockState crop, BlockPos pos, Direction face, @Nullable BlockHitResult hitResult, P player, InteractionHand hand) { super(player, hand, pos, face); this.level = level; this.crop = crop; @@ -89,7 +89,7 @@ public BlockState getCrop() { * Event triggered when checking whether a crop can be harvested.
* Fired on both sides. */ - public static class HarvestCheckEvent extends ForgeHarvestEvent implements HarvestEvent.HarvestCheckEvent { + public static class HarvestCheckEvent extends NeoForgeHarvestEvent implements HarvestEvent.HarvestCheckEvent { /** * Whether the crop can be harvested. */ @@ -123,7 +123,7 @@ public void setCanHarvest(boolean canHarvest) { * Event triggered before harvesting.
* Fired on server side only. */ - public static class BeforeHarvestEvent extends ForgeHarvestEvent implements HarvestEvent.BeforeHarvestEvent { + public static class BeforeHarvestEvent extends NeoForgeHarvestEvent implements HarvestEvent.BeforeHarvestEvent { /** * @param level {@link #level}. * @param crop {@link #crop}. @@ -142,7 +142,7 @@ public static class BeforeHarvestEvent extends ForgeHarvestEvent * Fired on server side only. */ - public static class HarvestDropsEvent extends ForgeHarvestEvent implements ICancellableEvent, HarvestEvent.HarvestDropsEvent { + public static class HarvestDropsEvent extends NeoForgeHarvestEvent implements ICancellableEvent, HarvestEvent.HarvestDropsEvent { /** * Reference to the default drops. */ @@ -194,7 +194,7 @@ public void cancel() { * Event triggered after harvesting.
* Fired on server side only. */ - public static class AfterHarvestEvent extends ForgeHarvestEvent implements HarvestEvent.AfterHarvestEvent { + public static class AfterHarvestEvent extends NeoForgeHarvestEvent implements HarvestEvent.AfterHarvestEvent { /** * @param level {@link #level}. * @param crop {@link #crop}. diff --git a/neoforge/src/main/java/it/crystalnest/harvest_with_ease/handler/NeoForgeHarvestHandler.java b/neoforge/src/main/java/it/crystalnest/harvest_with_ease/handler/NeoForgeHarvestHandler.java index 933f718..9f18eef 100644 --- a/neoforge/src/main/java/it/crystalnest/harvest_with_ease/handler/NeoForgeHarvestHandler.java +++ b/neoforge/src/main/java/it/crystalnest/harvest_with_ease/handler/NeoForgeHarvestHandler.java @@ -35,7 +35,10 @@ private static void handle(BlockEvent.BreakEvent event) { */ @SubscribeEvent(priority = EventPriority.HIGH) private static void handle(PlayerInteractEvent.RightClickBlock event) { - if (canInteract(event.getEntity(), event) && handle(event.getLevel(), event.getLevel().getBlockState(event.getHitVec().getBlockPos()), event.getHitVec().getDirection(), event.getHitVec().getBlockPos(), event.getHitVec(), event.getEntity(), event.getHand())) { + if ( + canInteract(event.getEntity(), event) && + handle(event.getLevel(), event.getLevel().getBlockState(event.getHitVec().getBlockPos()), event.getHitVec().getDirection(), event.getHitVec().getBlockPos(), event.getHitVec(), event.getEntity(), event.getHand()) + ) { event.setCancellationResult(InteractionResult.SUCCESS); event.setCanceled(true); }