From 22d5cb80686ec67a0c738122072de0299f594d0f Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 6 Oct 2019 13:26:29 -0700 Subject: [PATCH] loiter around ores to anticipate a possible drop --- src/api/java/baritone/api/Settings.java | 10 ++- .../baritone/process/GetToBlockProcess.java | 7 +- .../java/baritone/process/MineProcess.java | 64 +++++++++++++------ 3 files changed, 54 insertions(+), 27 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 8d54cbde..776d8e61 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -30,8 +30,8 @@ import java.awt.*; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.util.List; import java.util.*; +import java.util.List; import java.util.function.Consumer; /** @@ -798,6 +798,14 @@ public final class Settings { */ public final Setting mineScanDroppedItems = new Setting<>(true); + /** + * While mining, wait this number of milliseconds after mining an ore to see if it will drop an item + * instead of immediately going onto the next one + *

+ * Thanks Louca + */ + public final Setting mineDropLoiterDurationMSThanksLouca = new Setting<>(250L); + /** * Trim incorrect positions too far away, helps performance but hurts reliability in very large schematics */ diff --git a/src/main/java/baritone/process/GetToBlockProcess.java b/src/main/java/baritone/process/GetToBlockProcess.java index 5c1d7783..d6b405c1 100644 --- a/src/main/java/baritone/process/GetToBlockProcess.java +++ b/src/main/java/baritone/process/GetToBlockProcess.java @@ -33,10 +33,7 @@ import net.minecraft.init.Blocks; import net.minecraft.inventory.ContainerPlayer; import net.minecraft.util.math.BlockPos; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Optional; +import java.util.*; public final class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBlockProcess { @@ -175,7 +172,7 @@ public final class GetToBlockProcess extends BaritoneProcessHelper implements IG } private synchronized void rescan(List known, CalculationContext context) { - List positions = MineProcess.searchWorld(context, new BlockOptionalMetaLookup(gettingTo), 64, known, blacklist); + List positions = MineProcess.searchWorld(context, new BlockOptionalMetaLookup(gettingTo), 64, known, blacklist, Collections.emptyList()); positions.removeIf(blacklist::contains); knownLocations = positions; } diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index 4043e627..a76121b8 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -39,7 +39,6 @@ import net.minecraft.entity.item.EntityItem; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; import java.util.*; import java.util.stream.Collectors; @@ -58,6 +57,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro private BlockOptionalMetaLookup filter; private List knownOreLocations; private List blacklist; // inaccessible + private Map anticipatedDrops; private BlockPos branchPoint; private GoalRunAway branchPointRunaway; private int desiredQuantity; @@ -101,6 +101,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro cancel(); return null; } + updateLoucaSystem(); int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.value; List curr = new ArrayList<>(knownOreLocations); if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain @@ -141,6 +142,23 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro return command; } + private void updateLoucaSystem() { + Map copy = new HashMap<>(anticipatedDrops); + ctx.getSelectedBlock().ifPresent(pos -> { + if (knownOreLocations.contains(pos)) { + copy.put(pos, System.currentTimeMillis() + Baritone.settings().mineDropLoiterDurationMSThanksLouca.value); + } + }); + // elaborate dance to avoid concurrentmodificationexcepption since rescan thread reads this + // don't want to slow everything down with a gross lock do we now + for (BlockPos pos : anticipatedDrops.keySet()) { + if (copy.get(pos) < System.currentTimeMillis()) { + copy.remove(pos); + } + } + anticipatedDrops = copy; + } + @Override public void onLostControl() { mine(0, (BlockOptionalMetaLookup) null); @@ -155,9 +173,10 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro boolean legit = Baritone.settings().legitMine.value; List locs = knownOreLocations; if (!locs.isEmpty()) { - List locs2 = prune(new CalculationContext(baritone), new ArrayList<>(locs), filter, ORE_LOCATIONS_COUNT, blacklist); + CalculationContext context = new CalculationContext(baritone); + List locs2 = prune(context, new ArrayList<>(locs), filter, ORE_LOCATIONS_COUNT, blacklist, droppedItemsScan()); // can't reassign locs, gotta make a new var locs2, because we use it in a lambda right here, and variables you use in a lambda must be effectively final - Goal goal = new GoalComposite(locs2.stream().map(loc -> coalesce(loc, locs2)).toArray(Goal[]::new)); + Goal goal = new GoalComposite(locs2.stream().map(loc -> coalesce(loc, locs2, context)).toArray(Goal[]::new)); knownOreLocations = locs2; return new PathingCommand(goal, legit ? PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH : PathingCommandType.REVALIDATE_GOAL_AND_PATH); } @@ -197,8 +216,9 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro if (Baritone.settings().legitMine.value) { return; } - List locs = searchWorld(context, filter, ORE_LOCATIONS_COUNT, already, blacklist); - locs.addAll(droppedItemsScan(filter, ctx.world())); + List dropped = droppedItemsScan(); + List locs = searchWorld(context, filter, ORE_LOCATIONS_COUNT, already, blacklist, dropped); + locs.addAll(dropped); if (locs.isEmpty()) { logDirect("No locations for " + filter + " known, cancelling"); cancel(); @@ -207,19 +227,19 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro knownOreLocations = locs; } - private boolean internalMiningGoal(BlockPos pos, IPlayerContext ctx, List locs) { + private boolean internalMiningGoal(BlockPos pos, CalculationContext context, List locs) { // Here, BlockStateInterface is used because the position may be in a cached chunk (the targeted block is one that is kept track of) if (locs.contains(pos)) { return true; } - IBlockState state = BlockStateInterface.get(ctx, pos); + IBlockState state = context.bsi.get0(pos); if (Baritone.settings().internalMiningAirException.value && state.getBlock() instanceof BlockAir) { return true; } - return filter.has(state); + return filter.has(state) && plausibleToBreak(context, pos); } - private Goal coalesce(BlockPos loc, List locs) { + private Goal coalesce(BlockPos loc, List locs, CalculationContext context) { boolean assumeVerticalShaftMine = !(baritone.bsi.get0(loc.up()).getBlock() instanceof BlockFalling); if (!Baritone.settings().forceInternalMining.value) { if (assumeVerticalShaftMine) { @@ -230,9 +250,9 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro return new GoalTwoBlocks(loc); } } - boolean upwardGoal = internalMiningGoal(loc.up(), ctx, locs); - boolean downwardGoal = internalMiningGoal(loc.down(), ctx, locs); - boolean doubleDownwardGoal = internalMiningGoal(loc.down(2), ctx, locs); + boolean upwardGoal = internalMiningGoal(loc.up(), context, locs); + boolean downwardGoal = internalMiningGoal(loc.down(), context, locs); + boolean doubleDownwardGoal = internalMiningGoal(loc.down(2), context, locs); if (upwardGoal == downwardGoal) { // symmetric if (doubleDownwardGoal && assumeVerticalShaftMine) { // we have a checkerboard like pattern @@ -281,12 +301,12 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro } } - public static List droppedItemsScan(BlockOptionalMetaLookup filter, World world) { + public List droppedItemsScan() { if (!Baritone.settings().mineScanDroppedItems.value) { return Collections.emptyList(); } List ret = new ArrayList<>(); - for (Entity entity : world.loadedEntityList) { + for (Entity entity : ctx.world().loadedEntityList) { if (entity instanceof EntityItem) { EntityItem ei = (EntityItem) entity; if (filter.has(ei.getItem())) { @@ -294,10 +314,11 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro } } } + ret.addAll(anticipatedDrops.keySet()); return ret; } - public static List searchWorld(CalculationContext ctx, BlockOptionalMetaLookup filter, int max, List alreadyKnown, List blacklist) { + public static List searchWorld(CalculationContext ctx, BlockOptionalMetaLookup filter, int max, List alreadyKnown, List blacklist, List dropped) { List locs = new ArrayList<>(); List untracked = new ArrayList<>(); for (BlockOptionalMeta bom : filter.blocks()) { @@ -318,7 +339,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro } } - locs = prune(ctx, locs, filter, max, blacklist); + locs = prune(ctx, locs, filter, max, blacklist, dropped); if (!untracked.isEmpty() || (Baritone.settings().extendCacheOnThreshold.value && locs.size() < max)) { locs.addAll(WorldScanner.INSTANCE.scanChunkRadius( @@ -332,11 +353,12 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro locs.addAll(alreadyKnown); - return prune(ctx, locs, filter, max, blacklist); + return prune(ctx, locs, filter, max, blacklist, dropped); } private void addNearby() { - knownOreLocations.addAll(droppedItemsScan(filter, ctx.world())); + List dropped = droppedItemsScan(); + knownOreLocations.addAll(dropped); BlockPos playerFeet = ctx.playerFeet(); BlockStateInterface bsi = new BlockStateInterface(ctx); int searchDist = 10; @@ -355,11 +377,10 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro } } } - knownOreLocations = prune(new CalculationContext(baritone), knownOreLocations, filter, ORE_LOCATIONS_COUNT, blacklist); + knownOreLocations = prune(new CalculationContext(baritone), knownOreLocations, filter, ORE_LOCATIONS_COUNT, blacklist, dropped); } - private static List prune(CalculationContext ctx, List locs2, BlockOptionalMetaLookup filter, int max, List blacklist) { - List dropped = droppedItemsScan(filter, ctx.world); + private static List prune(CalculationContext ctx, List locs2, BlockOptionalMetaLookup filter, int max, List blacklist, List dropped) { dropped.removeIf(drop -> { for (BlockPos pos : locs2) { if (pos.distanceSq(drop) <= 9 && filter.has(ctx.get(pos.getX(), pos.getY(), pos.getZ())) && MineProcess.plausibleToBreak(ctx, pos)) { // TODO maybe drop also has to be supported? no lava below? @@ -416,6 +437,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro this.blacklist = new ArrayList<>(); this.branchPoint = null; this.branchPointRunaway = null; + this.anticipatedDrops = new HashMap<>(); if (filter != null) { rescan(new ArrayList<>(), new CalculationContext(baritone)); }