From 5b67aa04c42c8e8539c1306be10e14ef3a2db3cb Mon Sep 17 00:00:00 2001 From: nossr50 Date: Sat, 12 Apr 2025 13:23:35 -0700 Subject: [PATCH] support for various new additions from 1.21.5 --- Changelog.txt | 16 ++ .../skills/herbalism/HerbalismManager.java | 160 +++++++----------- .../gmail/nossr50/util/MaterialMapStore.java | 1 + src/main/resources/config.yml | 7 + src/main/resources/experience.yml | 7 + 5 files changed, 88 insertions(+), 103 deletions(-) diff --git a/Changelog.txt b/Changelog.txt index 809115689..ff7387feb 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,9 +1,25 @@ Version 2.2.035 + Support for new additions from Minecraft 1.21.5 + Added 'Bush' to experience.yml for Herbalism + Added 'Bush' to config.yml Bonus Drops for Herbalism + Added 'Cactus_Flower' to experience.yml for Herbalism + Added 'Cactus_Flower' to config.yml Bonus Drops for Herbalism + Added 'Firefly_Bush' to experience.yml for Herbalism + Added 'Firefly_Bush' to config.yml Bonus Drops for Herbalism + Added 'Leaf_Litter' to experience.yml for Herbalism + Added 'Leaf_Litter' to config.yml Bonus Drops for Herbalism + Added 'Short_Dry_Grass' to experience.yml for Herbalism + Added 'Short_Dry_Grass' to config.yml Bonus Drops for Herbalism + Added 'Tall_Dry_Grass' to experience.yml for Herbalism + Added 'Tall_Dry_Grass' to config.yml Bonus Drops for Herbalism + Added 'Wildflowers' to experience.yml for Herbalism + Added 'Wildflowers' to config.yml Bonus Drops for Herbalism Swords subskill Stab is now configurable in advanced.yml Added 'Skills.Swords.Stab.Base_Damage' to advanced.yml Added 'Skills.Swords.Stab.Per_Rank_Multiplier' to advanced.yml NOTES: + The mob variants will use the "base" mob definition for values for now, such a a warm chicken using chicken values from experience.yml The new config settings will be added automatically to advanced.yml Version 2.2.034 diff --git a/src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismManager.java b/src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismManager.java index b73964a7d..bf3c5ac7c 100644 --- a/src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismManager.java +++ b/src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismManager.java @@ -50,9 +50,12 @@ import static java.util.Objects.requireNonNull; public class HerbalismManager extends SkillManager { private final static HashMap plantBreakLimits; + private static final String CACTUS_STR = "cactus"; + private static final String CACTUS_FLOWER_STR = "cactus_flower"; + static { plantBreakLimits = new HashMap<>(); - plantBreakLimits.put("cactus", 3); + plantBreakLimits.put(CACTUS_STR, 3); plantBreakLimits.put("bamboo", 20); plantBreakLimits.put("sugar_cane", 3); plantBreakLimits.put("kelp", 26); @@ -68,10 +71,13 @@ public class HerbalismManager extends SkillManager { if (!RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.HERBALISM_GREEN_THUMB)) return false; - Player player = getPlayer(); - ItemStack item = player.getInventory().getItemInMainHand(); + final Player player = getPlayer(); + final ItemStack item = player.getInventory().getItemInMainHand(); - return item.getAmount() > 0 && item.getType() == Material.WHEAT_SEEDS && BlockUtils.canMakeMossy(blockState) && Permissions.greenThumbBlock(player, blockState.getType()); + return item.getAmount() > 0 + && item.getType() == Material.WHEAT_SEEDS + && BlockUtils.canMakeMossy(blockState.getBlock()) + && Permissions.greenThumbBlock(player, blockState.getType()); } public boolean canUseShroomThumb(BlockState blockState) { @@ -163,10 +169,6 @@ public class HerbalismManager extends SkillManager { return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.HERBALISM_HYLIAN_LUCK); } - public boolean canGreenTerraBlock(BlockState blockState) { - return mmoPlayer.getAbilityMode(SuperAbilityType.GREEN_TERRA) && BlockUtils.canMakeMossy(blockState); - } - public boolean canActivateAbility() { return mmoPlayer.getToolPreparationMode(ToolType.HOE) && Permissions.greenTerra(getPlayer()); } @@ -222,9 +224,9 @@ public class HerbalismManager extends SkillManager { * @param blockBreakEvent The Block Break Event to process */ public void processHerbalismBlockBreakEvent(BlockBreakEvent blockBreakEvent) { - Player player = getPlayer(); + final Player player = getPlayer(); - Block block = blockBreakEvent.getBlock(); + final Block block = blockBreakEvent.getBlock(); if (mcMMO.p.getGeneralConfig().getHerbalismPreventAFK() && player.isInsideVehicle()) { if (block.hasMetadata(MetadataConstants.METADATA_KEY_REPLANT)) { @@ -235,7 +237,7 @@ public class HerbalismManager extends SkillManager { //Check if the plant was recently replanted if (block.getBlockData() instanceof Ageable ageableCrop) { - if (block.getMetadata(MetadataConstants.METADATA_KEY_REPLANT).size() >= 1) { + if (!block.getMetadata(MetadataConstants.METADATA_KEY_REPLANT).isEmpty()) { if (block.getMetadata(MetadataConstants.METADATA_KEY_REPLANT).get(0).asBoolean()) { if (isAgeableMature(ageableCrop)) { block.removeMetadata(MetadataConstants.METADATA_KEY_REPLANT, mcMMO.p); @@ -254,9 +256,9 @@ public class HerbalismManager extends SkillManager { */ //Grab all broken blocks - HashSet brokenBlocks = getBrokenHerbalismBlocks(blockBreakEvent); + final HashSet brokenBlocks = getBrokenHerbalismBlocks(blockBreakEvent); - if (brokenBlocks.size() == 0) + if (brokenBlocks.isEmpty()) return; //Handle rewards, xp, ability interactions, etc @@ -272,7 +274,8 @@ public class HerbalismManager extends SkillManager { if (blockBreakEvent.isCancelled()) return; - BlockState originalBreak = blockBreakEvent.getBlock().getState(); + final BlockState originalBreak = blockBreakEvent.getBlock().getState(); + // TODO: Storing this boolean for no reason, refactor boolean greenThumbActivated = false; //TODO: The design of Green Terra needs to change, this is a mess @@ -322,12 +325,12 @@ public class HerbalismManager extends SkillManager { } //Give out XP to the non-chorus blocks - if (noDelayPlantBlocks.size() > 0) { + if (!noDelayPlantBlocks.isEmpty()) { //Note: Will contain 1 chorus block if the original block was a chorus block, this is to prevent delays for the XP bar awardXPForPlantBlocks(noDelayPlantBlocks); } - if (delayedChorusBlocks.size() > 0) { + if (!delayedChorusBlocks.isEmpty()) { //Check XP for chorus blocks DelayedHerbalismXPCheckTask delayedHerbalismXPCheckTask = new DelayedHerbalismXPCheckTask(mmoPlayer, delayedChorusBlocks); @@ -356,15 +359,9 @@ public class HerbalismManager extends SkillManager { //Check for double drops if (!mcMMO.getUserBlockTracker().isIneligible(brokenPlant)) { - /* - * * Natural Blocks - * - * - * */ - //Not all things that are natural should give double drops, make sure its fully mature as well if (plantData instanceof Ageable ageable) { @@ -378,13 +375,9 @@ public class HerbalismManager extends SkillManager { markForBonusDrops(brokenPlant); } } else { - /* - * * Unnatural Blocks - * */ - //If it's a crop, we need to reward XP when its fully grown if (isAgeableAndFullyMature(plantData) && !isBizarreAgeable(plantData)) { //Add metadata to mark this block for double or triple drops @@ -401,7 +394,7 @@ public class HerbalismManager extends SkillManager { */ public boolean isBizarreAgeable(BlockData blockData) { if (blockData instanceof Ageable) { - //Catcus and Sugar Canes cannot be trusted + // Cactus and Sugar Canes cannot be trusted return switch (blockData.getMaterial()) { case CACTUS, KELP, SUGAR_CANE, BAMBOO -> true; default -> false; @@ -440,12 +433,8 @@ public class HerbalismManager extends SkillManager { if (mcMMO.getUserBlockTracker().isIneligible(brokenBlockNewState)) { /* - * * Unnatural Blocks - * - * */ - //If its a Crop we need to reward XP when its fully grown if (isAgeableAndFullyMature(plantData) && !isBizarreAgeable(plantData)) { xpToReward += ExperienceConfig.getInstance().getXp(PrimarySkillType.HERBALISM, brokenBlockNewState.getType()); @@ -457,13 +446,9 @@ public class HerbalismManager extends SkillManager { mcMMO.getUserBlockTracker().setEligible(brokenBlockNewState); } else { /* - * * Natural Blocks - * - * */ - - //Calculate XP + // Calculate XP if (plantData instanceof Ageable plantAgeable) { if (isAgeableMature(plantAgeable) || isBizarreAgeable(plantData)) { @@ -481,7 +466,7 @@ public class HerbalismManager extends SkillManager { } if (mmoPlayer.isDebugMode()) { - mmoPlayer.getPlayer().sendMessage("Plants processed: "+brokenPlants.size()); + mmoPlayer.getPlayer().sendMessage("Plants processed: " + brokenPlants.size()); } //Reward XP @@ -489,7 +474,6 @@ public class HerbalismManager extends SkillManager { // get first block from hash set using stream API final Block firstBlock = brokenPlants.stream().findFirst().orElse(null); if (firstBlock != null - && firstXpReward != -1 && ExperienceConfig.getInstance().limitXPOnTallPlants() && plantBreakLimits.containsKey(firstBlock.getType().getKey().getKey())) { int limit = plantBreakLimits.get(firstBlock.getType().getKey().getKey()) * firstXpReward; @@ -501,16 +485,6 @@ public class HerbalismManager extends SkillManager { } } - private int getNaturalGrowthLimit(Material brokenPlant) { - // This is an exploit counter-measure to prevent players from growing unnaturally tall plants and reaping XP - if (plantBreakLimits.containsKey(brokenPlant.getKey().getKey())) { - return plantBreakLimits.get(brokenPlant.getKey().getKey()); - } else { - return 0; - } - } - - public boolean isAgeableMature(Ageable ageable) { return ageable.getAge() == ageable.getMaximumAge() && ageable.getAge() != 0; @@ -529,7 +503,7 @@ public class HerbalismManager extends SkillManager { int blocksGivingXP = 0; for(BlockSnapshot blockSnapshot : brokenPlants) { - BlockState brokenBlockNewState = blockSnapshot.getBlockRef().getState(); + final BlockState brokenBlockNewState = blockSnapshot.getBlockRef().getState(); //Remove metadata from the snapshot of blocks if (brokenBlockNewState.hasMetadata(MetadataConstants.METADATA_KEY_BONUS_DROPS)) { @@ -570,65 +544,66 @@ public class HerbalismManager extends SkillManager { */ private HashSet getBrokenHerbalismBlocks(@NotNull BlockBreakEvent blockBreakEvent) { //Get an updated capture of this block - BlockState originBlockState = blockBreakEvent.getBlock().getState(); - Material originBlockMaterial = originBlockState.getType(); - HashSet blocksBroken = new HashSet<>(); //Blocks broken + final BlockState originBlockState = blockBreakEvent.getBlock().getState(); + final Material originBlockMaterial = originBlockState.getType(); + final HashSet blocksBroken = new HashSet<>(); //Blocks broken //Add the initial block blocksBroken.add(originBlockState.getBlock()); if (!isOneBlockPlant(originBlockMaterial)) { //If the block is a multi-block structure, capture a set of all blocks broken and return that - blocksBroken = getBrokenBlocksMultiBlockPlants(originBlockState); + addBrokenBlocksMultiBlockPlants(originBlockState, blocksBroken); } //Return all broken plant-blocks return blocksBroken; } - private HashSet getBrokenChorusBlocks(BlockState originalBreak) { - return grabChorusTreeBrokenBlocksRecursive(originalBreak.getBlock(), new HashSet<>()); - } - - private HashSet grabChorusTreeBrokenBlocksRecursive(Block currentBlock, HashSet traversed) { + private void addChorusTreeBrokenBlocks(Block currentBlock, Set traversed) { if (!isChorusTree(currentBlock.getType())) - return traversed; + return; // Prevent any infinite loops, who needs more than 256 chorus anyways if (traversed.size() > 256) - return traversed; + return; if (!traversed.add(currentBlock)) - return traversed; + return; //Grab all Blocks in the Tree for (BlockFace blockFace : new BlockFace[] { BlockFace.UP, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST ,BlockFace.WEST}) - grabChorusTreeBrokenBlocksRecursive(currentBlock.getRelative(blockFace, 1), traversed); - - traversed.add(currentBlock); - - return traversed; + addChorusTreeBrokenBlocks(currentBlock.getRelative(blockFace, 1), traversed); } - /** - * Grab a set of all plant blocks that are broken as a result of this event - * The method to grab these blocks is a bit hacky and does not hook into the API - * Basically we expect the blocks to be broken if this event is not cancelled and we determine which block are broken on our end rather than any event state captures - * - * @return a set of plant-blocks broken from this event - */ - protected HashSet getBrokenBlocksMultiBlockPlants(BlockState brokenBlock) { - //Track the broken blocks - HashSet brokenBlocks; + protected void addBrokenBlocksMultiBlockPlants(BlockState brokenBlock, Set brokenBlocks) { if (isChorusBranch(brokenBlock.getType())) { - brokenBlocks = getBrokenChorusBlocks(brokenBlock); + addChorusTreeBrokenBlocks(brokenBlock.getBlock(), brokenBlocks); + } else if (isCactus(brokenBlock.getType())) { + addCactusBlocks(brokenBlock.getBlock(), brokenBlocks); } else { - brokenBlocks = getBlocksBrokenAboveOrBelow( - brokenBlock, false, mcMMO.getMaterialMapStore().isMultiBlockHangingPlant(brokenBlock.getType())); + addBlocksBrokenAboveOrBelow(brokenBlock.getBlock(), brokenBlocks, mcMMO.getMaterialMapStore().isMultiBlockHangingPlant(brokenBlock.getType())); } + } - return brokenBlocks; + private void addCactusBlocks(Block currentBlock, Set traversed) { + if (!isCactus(currentBlock.getType())) + return; + + if (traversed.size() > 4) // Max size 3 cactus + flower + return; + + if (!traversed.add(currentBlock)) + return; + + addCactusBlocks(currentBlock.getRelative(BlockFace.UP), traversed); + addCactusBlocks(currentBlock.getRelative(BlockFace.DOWN), traversed); + } + + private boolean isCactus(Material material) { + return material.getKey().getKey().equalsIgnoreCase(CACTUS_STR) + || material.getKey().getKey().equalsIgnoreCase(CACTUS_FLOWER_STR); } private boolean isChorusBranch(Material blockType) { @@ -639,25 +614,7 @@ public class HerbalismManager extends SkillManager { return blockType == Material.CHORUS_PLANT || blockType == Material.CHORUS_FLOWER; } - /** - * Grabs blocks upwards from a target block - * A lot of Plants/Crops in Herbalism only break vertically from a broken block - * The vertical search returns early if it runs into anything that is not a multi-block plant - * Multi-block plants are hard-coded and kept in {@link MaterialMapStore} - * - * @param originBlock The point of the "break" - * @param inclusive Whether to include the origin block - * @param below Whether to search down instead of up. - * @return A set of blocks above the target block which can be assumed to be broken - */ - private HashSet getBlocksBrokenAboveOrBelow(BlockState originBlock, boolean inclusive, boolean below) { - HashSet brokenBlocks = new HashSet<>(); - Block block = originBlock.getBlock(); - - //Add the initial block to the set - if (inclusive) - brokenBlocks.add(block); - + private void addBlocksBrokenAboveOrBelow(Block originBlock, Set brokenBlocks, boolean below) { //Limit our search int maxHeight = 512; @@ -665,8 +622,7 @@ public class HerbalismManager extends SkillManager { // Search vertically for multi-block plants, exit early if any non-multi block plants for (int y = 0; y < maxHeight; y++) { - //TODO: Should this grab state? It would be more expensive.. - Block relativeBlock = block.getRelative(relativeFace, y); + final Block relativeBlock = originBlock.getRelative(relativeFace, y); //Abandon our search if the block isn't multi if (isOneBlockPlant(relativeBlock.getType())) @@ -674,8 +630,6 @@ public class HerbalismManager extends SkillManager { brokenBlocks.add(relativeBlock); } - - return brokenBlocks; } /** diff --git a/src/main/java/com/gmail/nossr50/util/MaterialMapStore.java b/src/main/java/com/gmail/nossr50/util/MaterialMapStore.java index 48df69883..da7a21da5 100644 --- a/src/main/java/com/gmail/nossr50/util/MaterialMapStore.java +++ b/src/main/java/com/gmail/nossr50/util/MaterialMapStore.java @@ -1003,6 +1003,7 @@ public class MaterialMapStore { private void fillMultiBlockPlantSet() { //Multi-Block Plants multiBlockPlant.add("cactus"); + multiBlockPlant.add("cactus_flower"); multiBlockPlant.add("chorus_plant"); multiBlockPlant.add("chorus_flower"); multiBlockPlant.add("sugar_cane"); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 31d3a692e..936ea67b7 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -483,6 +483,13 @@ Green_Thumb_Replanting_Crops: ### Bonus_Drops: Herbalism: + Bush: true + Cactus_Flower: true + Firefly_Bush: true + Leaf_Litter: true + Short_Dry_Grass: true + Tall_Dry_Grass: true + Wildflowers: true Eyeblossom: true Open_Eyeblossom: true Closed_Eyeblossom: true diff --git a/src/main/resources/experience.yml b/src/main/resources/experience.yml index d35967b49..f6176ba6a 100644 --- a/src/main/resources/experience.yml +++ b/src/main/resources/experience.yml @@ -330,6 +330,13 @@ Experience_Values: Brown_Mushroom_Block: 70 Mushroom_Stem: 80 Herbalism: + Bush: 11 + Cactus_Flower: 60 + Firefly_Bush: 15 + Leaf_Litter: 2 + Short_Dry_Grass: 6 + Tall_Dry_Grass: 12 + Wildflowers: 15 Eyeblossom: 66 Open_Eyeblossom: 66 Closed_Eyeblossom: 66