Limit XP on certain plants which can become unnaturally tall Fixes #5045

This commit is contained in:
nossr50 2024-07-27 15:42:18 -07:00
parent 486dc1344d
commit afa4260d0d
4 changed files with 52 additions and 3 deletions

View File

@ -2,11 +2,13 @@ Version 2.2.018
Fixed a probability bug where certain skills would max out in chance to succeed well before they were supposed to (such as Dodge)
Blast Mining will no longer drop mob spawners (see notes)
(Codebase) Added more unit tests for Probability and RNG
The Herbalism XP gained when breaking certain plants that can grow unnaturally tall vertically (bamboo, kelp) is now capped to the most it could give when naturally grown, this can be disabled in experience.yml
Added 'ExploitFix.LimitTallPlantFarming' to experience.yml
NOTES:
This probability bug was a big oopsie and showed a gap in unit test coverage, I've added that coverage and a bug like this in theory shouldn't happen again.
In a future version I will add configuration for admins to control what blocks are not allowed to be dropped by blast mining.
A setting has been added to disable player-created super tall plants from giving full XP, this is on by default, you can tun it off in experience.yml via 'ExploitFix.LimitTallPlantFarming'
Version 2.2.017
Fixed a bug with default Mace permissions (thanks SrBedrock)
Fixed Blast Mining being almost completely broken

View File

@ -496,4 +496,8 @@ public class ExperienceConfig extends BukkitConfig {
public boolean preventStoneLavaFarming() {
return config.getBoolean("ExploitFix.LavaStoneAndCobbleFarming", true);
}
public boolean limitXPOnTallPlants() {
return config.getBoolean("ExploitFix.LimitTallPlantFarming", true);
}
}

View File

@ -46,6 +46,18 @@ import static com.gmail.nossr50.util.ItemUtils.removeItemIncludingOffHand;
import static java.util.Objects.requireNonNull;
public class HerbalismManager extends SkillManager {
private final static HashMap<String, Integer> plantBreakLimits;
static {
plantBreakLimits = new HashMap<>();
plantBreakLimits.put("cactus", 3);
plantBreakLimits.put("bamboo", 20);
plantBreakLimits.put("sugar_cane", 3);
plantBreakLimits.put("kelp", 26);
plantBreakLimits.put("kelp_plant", 26);
plantBreakLimits.put("chorus_plant", 22);
}
public HerbalismManager(McMMOPlayer mcMMOPlayer) {
super(mcMMOPlayer, PrimarySkillType.HERBALISM);
}
@ -408,6 +420,7 @@ public class HerbalismManager extends SkillManager {
public void awardXPForPlantBlocks(HashSet<Block> brokenPlants) {
int xpToReward = 0;
int firstXpReward = -1;
for(Block brokenPlantBlock : brokenPlants) {
BlockState brokenBlockNewState = brokenPlantBlock.getState();
@ -424,6 +437,8 @@ public class HerbalismManager extends SkillManager {
//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());
if (firstXpReward == -1)
firstXpReward = xpToReward;
}
//Mark it as natural again as it is being broken
@ -441,10 +456,14 @@ public class HerbalismManager extends SkillManager {
if (isAgeableMature(plantAgeable) || isBizarreAgeable(plantData)) {
xpToReward += ExperienceConfig.getInstance().getXp(PrimarySkillType.HERBALISM, brokenBlockNewState.getType());
if (firstXpReward == -1)
firstXpReward = xpToReward;
}
} else {
xpToReward += ExperienceConfig.getInstance().getXp(PrimarySkillType.HERBALISM, brokenPlantBlock.getType());
if (firstXpReward == -1)
firstXpReward = xpToReward;
}
}
}
@ -455,10 +474,31 @@ public class HerbalismManager extends SkillManager {
//Reward XP
if (xpToReward > 0) {
applyXpGain(xpToReward, XPGainReason.PVE, XPGainSource.SELF);
// 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;
// Plant may be unnaturally tall, limit XP
applyXpGain(Math.min(xpToReward, limit), XPGainReason.PVE, XPGainSource.SELF);
} else {
applyXpGain(xpToReward, XPGainReason.PVE, XPGainSource.SELF);
}
}
}
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;
@ -572,7 +612,8 @@ public class HerbalismManager extends SkillManager {
if (isChorusBranch(brokenBlock.getType())) {
brokenBlocks = getBrokenChorusBlocks(brokenBlock);
} else {
brokenBlocks = getBlocksBrokenAboveOrBelow(brokenBlock, false, mcMMO.getMaterialMapStore().isMultiBlockHangingPlant(brokenBlock.getType()));
brokenBlocks = getBlocksBrokenAboveOrBelow(
brokenBlock, false, mcMMO.getMaterialMapStore().isMultiBlockHangingPlant(brokenBlock.getType()));
}
return brokenBlocks;

View File

@ -34,6 +34,8 @@ ExploitFix:
# mcMMO normally doesn't process attacks against an Entity if it is an NPC from another plugin
# Of course, mcMMO doesn't know for sure whether something is an NPC, it checks a few known things, see our source code to see how
PreventPluginNPCInteraction: true
# This will limit XP gained from unnaturally tall plants, like those created by Bone Meal
LimitTallPlantFarming: true
Fishing_ExploitFix_Options:
MoveRange: 3
OverFishLimit: 10