Respect tool tier requirement for block breaking (#1837)

This commit is contained in:
Camotoy 2021-05-23 22:32:42 -04:00
parent 986701f06f
commit 1f83a5ac9f
No known key found for this signature in database
GPG Key ID: 7EEFB66FE798081F
3 changed files with 58 additions and 6 deletions

View File

@ -305,6 +305,7 @@
</replacement>
<replacement>
<token>String GIT_VERSION = ".*"</token>
<!--suppress UnresolvedMavenProperty -->
<value>String GIT_VERSION = "git-${git.branch}-${git.commit.id.abbrev}"</value>
</replacement>
</replacements>

View File

@ -47,6 +47,10 @@ public class TagCache {
private IntList pickaxeEffective;
private IntList shovelEffective;
private IntList requiresStoneTool;
private IntList requiresIronTool;
private IntList requiresDiamondTool;
/* Items */
private IntList flowers;
private IntList foxFood;
@ -67,6 +71,10 @@ public class TagCache {
this.pickaxeEffective = IntList.of(blockTags.get("minecraft:mineable/pickaxe"));
this.shovelEffective = IntList.of(blockTags.get("minecraft:mineable/shovel"));
this.requiresStoneTool = IntList.of(blockTags.get("minecraft:needs_stone_tool"));
this.requiresIronTool = IntList.of(blockTags.get("minecraft:needs_iron_tool"));
this.requiresDiamondTool = IntList.of(blockTags.get("minecraft:needs_diamond_tool"));
Map<String, int[]> itemTags = packet.getTags().get("minecraft:item");
this.flowers = IntList.of(itemTags.get("minecraft:flowers"));
this.foxFood = IntList.of(itemTags.get("minecraft:fox_food"));
@ -82,6 +90,10 @@ public class TagCache {
this.pickaxeEffective = IntLists.emptyList();
this.shovelEffective = IntLists.emptyList();
this.requiresStoneTool = IntLists.emptyList();
this.requiresIronTool = IntLists.emptyList();
this.requiresDiamondTool = IntLists.emptyList();
this.flowers = IntLists.emptyList();
this.foxFood = IntLists.emptyList();
this.piglinLoved = IntLists.emptyList();
@ -119,4 +131,16 @@ public class TagCache {
int javaBlockId = blockMapping.getJavaBlockId();
return leaves.contains(javaBlockId) || wool.contains(javaBlockId);
}
public boolean requiresStoneTool(BlockMapping blockMapping) {
return requiresStoneTool.contains(blockMapping.getJavaBlockId());
}
public boolean requiresIronTool(BlockMapping blockMapping) {
return requiresIronTool.contains(blockMapping.getJavaBlockId());
}
public boolean requiresDiamondTool(BlockMapping blockMapping) {
return requiresDiamondTool.contains(blockMapping.getJavaBlockId());
}
}

View File

@ -83,11 +83,36 @@ public class BlockUtils {
}
}
//http://minecraft.gamepedia.com/Breaking
private static double calculateBreakTime(double blockHardness, String toolTier, boolean canHarvestWithHand, boolean correctTool,
private static boolean canToolTierBreakBlock(GeyserSession session, BlockMapping blockMapping, String toolTier) {
if (toolTier.equals("netherite") || toolTier.equals("diamond")) {
// As of 1.17, these tiers can mine everything that is mineable
return true;
}
switch (toolTier) {
// Use intentional fall-throughs to check each tier with this block
default:
if (session.getTagCache().requiresStoneTool(blockMapping)) {
return false;
}
case "stone":
if (session.getTagCache().requiresIronTool(blockMapping)) {
return false;
}
case "iron":
if (session.getTagCache().requiresDiamondTool(blockMapping)) {
return false;
}
}
return true;
}
// https://minecraft.gamepedia.com/Breaking
private static double calculateBreakTime(double blockHardness, String toolTier, boolean canHarvestWithHand, boolean correctTool, boolean canTierMineBlock,
String toolType, boolean isShearsEffective, int toolEfficiencyLevel, int hasteLevel, int miningFatigueLevel,
boolean insideOfWaterWithoutAquaAffinity, boolean outOfWaterButNotOnGround, boolean insideWaterAndNotOnGround) {
double baseTime = ((correctTool || canHarvestWithHand) ? 1.5 : 5.0) * blockHardness;
double baseTime = (((correctTool && canTierMineBlock) || canHarvestWithHand) ? 1.5 : 5.0) * blockHardness;
double speed = 1.0 / baseTime;
if (correctTool) {
@ -125,11 +150,13 @@ public class BlockUtils {
String toolType = "";
String toolTier = "";
boolean correctTool = false;
boolean toolCanBreak = false;
if (item instanceof ToolItemEntry) {
ToolItemEntry toolItem = (ToolItemEntry) item;
toolType = toolItem.getToolType();
toolTier = toolItem.getToolTier();
correctTool = correctTool(session, blockMapping, toolType);
toolCanBreak = canToolTierBreakBlock(session, blockMapping, toolTier);
}
int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(nbtData, "minecraft:efficiency");
int hasteLevel = 0;
@ -137,12 +164,12 @@ public class BlockUtils {
if (!isSessionPlayer) {
// Another entity is currently mining; we have all the information we know
return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolType, isShearsEffective,
return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolCanBreak, toolType, isShearsEffective,
toolEfficiencyLevel, hasteLevel, miningFatigueLevel, false,
false, false);
}
hasteLevel = session.getEffectCache().getEffectLevel(Effect.FASTER_DIG);
hasteLevel = Math.max(session.getEffectCache().getEffectLevel(Effect.FASTER_DIG), session.getEffectCache().getEffectLevel(Effect.CONDUIT_POWER));
miningFatigueLevel = session.getEffectCache().getEffectLevel(Effect.SLOWER_DIG);
boolean isInWater = session.getCollisionManager().isPlayerInWater();
@ -152,7 +179,7 @@ public class BlockUtils {
boolean outOfWaterButNotOnGround = (!isInWater) && (!session.getPlayerEntity().isOnGround());
boolean insideWaterNotOnGround = isInWater && !session.getPlayerEntity().isOnGround();
return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolType, isShearsEffective,
return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolCanBreak, toolType, isShearsEffective,
toolEfficiencyLevel, hasteLevel, miningFatigueLevel, insideOfWaterWithoutAquaAffinity,
outOfWaterButNotOnGround, insideWaterNotOnGround);
}