Compare commits
83 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ee119fc64 | ||
|
|
83265fcb54 | ||
|
|
e8b4f4d2b6 | ||
|
|
714c6773c3 | ||
|
|
2fac594315 | ||
|
|
4bec49de5b | ||
|
|
4eaa6e20c3 | ||
|
|
315cc26525 | ||
|
|
794a761243 | ||
|
|
5da14fcb3f | ||
|
|
1047d4ade9 | ||
|
|
0b8fa3ffe3 | ||
|
|
498e4e2d6c | ||
|
|
850c414e8f | ||
|
|
d5a8ed5cb1 | ||
|
|
dd8406c39a | ||
|
|
13469053b9 | ||
|
|
c4c85b4f49 | ||
|
|
af0c3bbd5c | ||
|
|
2fcf9ace64 | ||
|
|
47e1c67bd8 | ||
|
|
7e3aa6efdd | ||
|
|
7a2f26ef62 | ||
|
|
b64154e3b3 | ||
|
|
26256e7155 | ||
|
|
6599736e00 | ||
|
|
343bb20bd8 | ||
|
|
518fa1c74d | ||
|
|
0b72a8b4b3 | ||
|
|
c013d1e0d9 | ||
|
|
fe51220e3c | ||
|
|
44d757347b | ||
|
|
c136182e17 | ||
|
|
a1a9b4e6b9 | ||
|
|
f49df63183 | ||
|
|
96414b37f3 | ||
|
|
544168ff45 | ||
|
|
e0a618a791 | ||
|
|
3333797144 | ||
|
|
f7f003c0f9 | ||
|
|
236d02cb47 | ||
|
|
6e97fe2210 | ||
|
|
6741666c24 | ||
|
|
fcadf68c90 | ||
|
|
65cd6a92d3 | ||
|
|
a09bb0d538 | ||
|
|
2bf475d840 | ||
|
|
76cdaaace6 | ||
|
|
ce59ef559f | ||
|
|
fc3f183dce | ||
|
|
6b6eea2d8c | ||
|
|
e54652941b | ||
|
|
867c01ff86 | ||
|
|
87a9e67ba8 | ||
|
|
bf076f6246 | ||
|
|
75b54dfaec | ||
|
|
71a2219b07 | ||
|
|
ccc3de2d7c | ||
|
|
af11e64cec | ||
|
|
2c3dc5d6b1 | ||
|
|
71482cc984 | ||
|
|
3329db1dae | ||
|
|
926e2d5620 | ||
|
|
d2de8828e7 | ||
|
|
9fcae6560e | ||
|
|
2e8fdd43ee | ||
|
|
27e39c8083 | ||
|
|
a8f373d568 | ||
|
|
71491a7922 | ||
|
|
170c2d35c2 | ||
|
|
bc49b2d5ba | ||
|
|
f58b6b41cb | ||
|
|
ac1ac50158 | ||
|
|
d4103a924d | ||
|
|
bd64f73842 | ||
|
|
cac653ddd9 | ||
|
|
04ff365890 | ||
|
|
54ed6ce5a5 | ||
|
|
32ac46c8a9 | ||
|
|
7ab2cd2a45 | ||
|
|
a07fae6cdd | ||
|
|
3f6af51713 | ||
|
|
8c4e778506 |
1
.github/ISSUE_TEMPLATE.md
vendored
Normal file
1
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<!-- No UwU's or OwO's allowed -->
|
||||
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<!-- No UwU's or OwO's allowed -->
|
||||
@@ -45,6 +45,11 @@ that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
Project maintainers have the right and responsibility to immediately remove
|
||||
without any sort of dispute any issues or pull requests that do not align
|
||||
with their corresponding templates. Absolutely no leniancy shall be accepted
|
||||
with these terms.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
|
||||
11
Dockerfile
11
Dockerfile
@@ -1,17 +1,16 @@
|
||||
FROM debian:jessie
|
||||
FROM debian:stretch
|
||||
|
||||
RUN echo 'deb http://deb.debian.org/debian jessie-backports main' > /etc/apt/sources.list.d/jessie-backports.list
|
||||
RUN echo 'deb http://deb.debian.org/debian stretch-backports main' > /etc/apt/sources.list.d/stretch-backports.list
|
||||
|
||||
ENV DEBIAN_FRONTEND noninteractive
|
||||
|
||||
RUN apt update -y
|
||||
|
||||
RUN apt install --target-release jessie-backports \
|
||||
RUN apt install \
|
||||
openjdk-8-jdk \
|
||||
ca-certificates-java \
|
||||
--assume-yes
|
||||
|
||||
RUN apt install -qq --force-yes mesa-utils libgl1-mesa-glx libxcursor1 libxrandr2 libxxf86vm1 x11-xserver-utils xfonts-base xserver-common
|
||||
RUN apt install -qq --assume-yes mesa-utils libgl1-mesa-glx libxcursor1 libxrandr2 libxxf86vm1 x11-xserver-utils xfonts-base xserver-common
|
||||
|
||||
COPY . /code
|
||||
|
||||
@@ -21,4 +20,4 @@ WORKDIR /code
|
||||
# source: https://github.com/tectonicus/tectonicus/issues/60#issuecomment-154239173
|
||||
RUN dpkg -i scripts/xvfb_1.16.4-1_amd64.deb
|
||||
|
||||
RUN ./gradlew build
|
||||
RUN ./gradlew build
|
||||
|
||||
@@ -13,15 +13,16 @@
|
||||

|
||||

|
||||

|
||||

|
||||
[](https://minecraft.gamepedia.com/1.12.2)
|
||||
[](https://github.com/cabaletta/baritone/graphs/contributors/)
|
||||
[](https://github.com/cabaletta/baritone/commit/)
|
||||
[](https://impactdevelopment.github.io/)
|
||||
[](https://impactdevelopment.github.io/)
|
||||
[](https://wweclient.com/)
|
||||
[](https://github.com/zeroeightysix/KAMI/)
|
||||
[](https://futureclient.net/)
|
||||
[](https://github.com/fr1kin/ForgeHax)
|
||||
[](http://forthebadge.com)
|
||||
[](http://forthebadge.com)
|
||||
|
||||
A Minecraft pathfinder bot.
|
||||
|
||||
@@ -30,7 +31,7 @@ Baritone is the pathfinding system used in [Impact](https://impactdevelopment.gi
|
||||
This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
|
||||
the original version of the bot for Minecraft 1.8.9, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
|
||||
|
||||
Have committed at least once a day for the last 7 months =D 🦀
|
||||
Have committed at least once a day for the last 8 months =D 🦀
|
||||
|
||||
1Leijurv3DWTrGAfmmiTphjhXLvQiHg7K2
|
||||
|
||||
|
||||
2
SETUP.md
2
SETUP.md
@@ -1,7 +1,7 @@
|
||||
# Installation
|
||||
|
||||
## Prebuilt official releases
|
||||
These releases are not always completely up to date with latest features, and are only released from `master`. (so if you want `builder` branch for example, you'll have to build it yourself)
|
||||
These releases are not always completely up to date with latest features, and are only released from `master`. (so if you want `backfill-2` branch for example, you'll have to build it yourself)
|
||||
|
||||
Link to the releases page: [Releases](https://github.com/cabaletta/baritone/releases)
|
||||
|
||||
|
||||
6
USAGE.md
6
USAGE.md
@@ -34,7 +34,7 @@ Some common examples:
|
||||
- `cancel` or `stop` to stop everything
|
||||
- `goto portal` or `goto ender_chest` or `goto block_type` to go to a block. (in Impact, `.goto` is an alias for `.b goto` for the most part)
|
||||
- `mine diamond_ore` to mine diamond ore (turn on the setting `legitMine` to only mine ores that it can actually see. It will explore randomly around y=11 until it finds them.)
|
||||
- `click` to click your destination on the screen. left click to path into it, right click to path on top of it.
|
||||
- `click` to click your destination on the screen. left click to path into it, right click to path on top of it. left click and drag to clear an area.
|
||||
- `follow playerName` to follow a player. `follow` to follow the entity you're looking at (only works if it hitting range). `followplayers` to follow any players in range (combine with Kill Aura for a fun time).
|
||||
- `save waypointName` to save a waypoint. `goto waypointName` to go to it.
|
||||
- `axis` to go to an axis or diagonal axis at y=120 (`axisHeight` is a configurable setting, defaults to 120).
|
||||
@@ -42,6 +42,7 @@ Some common examples:
|
||||
- `render` to rerender the world in case `renderCachedChunks` is being glitchy
|
||||
- `version` to get the version of Baritone you're running
|
||||
- `damn` daniel
|
||||
- `build` to build a schematic. `build blah` will load `schematics/blah.schematic` and build it with the origin being your player feet. `build blah x y z` to set the origin. Any of those can be relative to your player (`~ 69 ~-420` would build at x=player x, y=69, z=player z-420).
|
||||
|
||||
For the rest of the commands, you can take a look at the code [here](https://github.com/cabaletta/baritone/blob/master/src/main/java/baritone/utils/ExampleBaritoneControl.java).
|
||||
|
||||
@@ -62,9 +63,6 @@ There are about a hundred settings, but here are some fun / interesting / import
|
||||
|
||||
# Troubleshooting / common issues
|
||||
|
||||
## Baritone highlights a block in green but gets completely stuck? Also I'm using Baritone with Future?
|
||||
Baritone is trying to right click to place a block there, but it can't since there's a conflicting mixin. Baritone can't force click right click when Future is also installed. Left click **does work** on recent Baritone even with Future, however. For now, turn off `allowPlace` and Baritone will only search for paths that don't require placing blocks to complete. `allowBreak` can remain on.
|
||||
|
||||
## Why doesn't Baritone respond to any of my chat commands?
|
||||
This could be one of many things.
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
group 'baritone'
|
||||
version '1.2.5'
|
||||
version '1.2.6'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
|
||||
2
scripts/proguard.pro
vendored
2
scripts/proguard.pro
vendored
@@ -21,6 +21,8 @@
|
||||
-keep class baritone.BaritoneProvider
|
||||
-keep class baritone.api.IBaritoneProvider
|
||||
|
||||
-keep class baritone.api.utils.MyChunkPos { *; } # even in standalone we need to keep this for gson reflect
|
||||
|
||||
# setting names are reflected from field names, so keep field names
|
||||
-keepclassmembers class baritone.api.Settings {
|
||||
public <fields>;
|
||||
|
||||
@@ -71,6 +71,18 @@ public interface IBaritone {
|
||||
*/
|
||||
IBuilderProcess getBuilderProcess();
|
||||
|
||||
/**
|
||||
* @return The {@link IExploreProcess} instance
|
||||
* @see IExploreProcess
|
||||
*/
|
||||
IExploreProcess getExploreProcess();
|
||||
|
||||
/**
|
||||
* @return The {@link IFarmProcess} instance
|
||||
* @see IFarmProcess
|
||||
*/
|
||||
IFarmProcess getFarmProcess();
|
||||
|
||||
/**
|
||||
* @return The {@link ICustomGoalProcess} instance
|
||||
* @see ICustomGoalProcess
|
||||
@@ -115,4 +127,6 @@ public interface IBaritone {
|
||||
* @see IEventBus
|
||||
*/
|
||||
IEventBus getGameEventHandler();
|
||||
|
||||
void openClick();
|
||||
}
|
||||
|
||||
@@ -18,13 +18,18 @@
|
||||
package baritone.api;
|
||||
|
||||
import baritone.api.utils.SettingsUtil;
|
||||
import baritone.api.utils.TypeUtils;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
import java.awt.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
@@ -58,7 +63,9 @@ public final class Settings {
|
||||
|
||||
/**
|
||||
* It doesn't actually take twenty ticks to place a block, this cost is so high
|
||||
* because we want to generally conserve blocks which might be limited
|
||||
* because we want to generally conserve blocks which might be limited.
|
||||
* <p>
|
||||
* Decrease to make Baritone more often consider paths that would require placing blocks
|
||||
*/
|
||||
public final Setting<Double> blockPlacementPenalty = new Setting<>(20D);
|
||||
|
||||
@@ -91,6 +98,11 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> assumeWalkOnWater = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* If you have Fire Resistance and Jesus then I guess you could turn this on lol
|
||||
*/
|
||||
public final Setting<Boolean> assumeWalkOnLava = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Assume step functionality; don't jump on an Ascend.
|
||||
*/
|
||||
@@ -108,7 +120,7 @@ public final class Settings {
|
||||
/**
|
||||
* If true, parkour is allowed to make jumps when standing on blocks at the maximum height, so player feet is y=256
|
||||
* <p>
|
||||
* Defaults to false because this fails on constantiam
|
||||
* Defaults to false because this fails on constantiam. Please let me know if this is ever disabled. Please.
|
||||
*/
|
||||
public final Setting<Boolean> allowJumpAt256 = new Setting<>(false);
|
||||
|
||||
@@ -121,15 +133,37 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> allowDiagonalDescend = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Allow mining the block directly beneath its feet
|
||||
* <p>
|
||||
* Turn this off to force it to make more staircases and less shafts
|
||||
*/
|
||||
public final Setting<Boolean> allowDownward = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Blocks that Baritone is allowed to place (as throwaway, for sneak bridging, pillaring, etc.)
|
||||
*/
|
||||
public final Setting<List<Item>> acceptableThrowawayItems = new Setting<>(new ArrayList<>(Arrays.asList(
|
||||
Item.getItemFromBlock(Blocks.DIRT),
|
||||
Item.getItemFromBlock(Blocks.COBBLESTONE),
|
||||
Item.getItemFromBlock(Blocks.NETHERRACK)
|
||||
Item.getItemFromBlock(Blocks.NETHERRACK),
|
||||
Item.getItemFromBlock(Blocks.STONE)
|
||||
)));
|
||||
|
||||
/**
|
||||
* Blocks that Baritone will attempt to avoid (Used in avoidance)
|
||||
*/
|
||||
public final Setting<List<Block>> blocksToAvoid = new Setting<>(new ArrayList<>(
|
||||
// Leave Empty by Default
|
||||
));
|
||||
|
||||
/**
|
||||
* Blocks that Baritone is not allowed to break
|
||||
*/
|
||||
public final Setting<List<Block>> blocksToAvoidBreaking = new Setting<>(new ArrayList<>(
|
||||
// e.g. crafting table, beds
|
||||
));
|
||||
|
||||
/**
|
||||
* Enables some more advanced vine features. They're honestly just gimmicks and won't ever be needed in real
|
||||
* pathing scenarios. And they can cause Baritone to get trapped indefinitely in a strange scenario.
|
||||
@@ -386,10 +420,12 @@ public final class Settings {
|
||||
* On save, delete from RAM any cached regions that are more than 1024 blocks away from the player
|
||||
* <p>
|
||||
* Temporarily disabled
|
||||
* <p>
|
||||
* Temporarily reenabled
|
||||
*
|
||||
* @see <a href="https://github.com/cabaletta/baritone/issues/248">Issue #248</a>
|
||||
*/
|
||||
public final Setting<Boolean> pruneRegionsFromRAM = new Setting<>(false);
|
||||
public final Setting<Boolean> pruneRegionsFromRAM = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Remember the contents of containers (chests, echests, furnaces)
|
||||
@@ -398,6 +434,11 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> containerMemory = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Fill in blocks behind you
|
||||
*/
|
||||
public final Setting<Boolean> backfill = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Print all the debug messages to chat
|
||||
*/
|
||||
@@ -424,6 +465,11 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> renderGoal = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Render selection boxes
|
||||
*/
|
||||
public final Setting<Boolean> renderSelectionBoxes = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Ignore depth when rendering the goal
|
||||
*/
|
||||
@@ -547,6 +593,45 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> exploreForBlocks = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* While exploring the world, offset the closest unloaded chunk by this much in both axes.
|
||||
* <p>
|
||||
* This can result in more efficient loading, if you set this to the render distance.
|
||||
*/
|
||||
public final Setting<Integer> worldExploringChunkOffset = new Setting<>(0);
|
||||
|
||||
/**
|
||||
* Take the 10 closest chunks, even if they aren't strictly tied for distance metric from origin.
|
||||
*/
|
||||
public final Setting<Integer> exploreChunkSetMinimumSize = new Setting<>(10);
|
||||
|
||||
/**
|
||||
* Replant nether wart
|
||||
*/
|
||||
public final Setting<Boolean> replantNetherWart = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* When the cache scan gives less blocks than the maximum threshold (but still above zero), scan the main world too.
|
||||
* <p>
|
||||
* Only if you have a beefy CPU and automatically mine blocks that are in cache
|
||||
*/
|
||||
public final Setting<Boolean> extendCacheOnThreshold = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Don't consider the next layer in builder until the current one is done
|
||||
*/
|
||||
public final Setting<Boolean> buildInLayers = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* How far to move before repeating the build. -1 for the size of the build in that axis. 0 to disable
|
||||
*/
|
||||
public final Setting<Integer> buildRepeatDistance = new Setting<>(0);
|
||||
|
||||
/**
|
||||
* What direction to repeat the build in
|
||||
*/
|
||||
public final Setting<EnumFacing> buildRepeatDirection = new Setting<>(EnumFacing.NORTH);
|
||||
|
||||
/**
|
||||
* While mining, should it also consider dropped items of the correct type as a pathing destination (as well as ore blocks)?
|
||||
*/
|
||||
@@ -639,6 +724,12 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> exploreUsePythagorean = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Turn this on if your exploration filter is enormous, you don't want it to check if it's done,
|
||||
* and you are just fine with it just hanging on completion
|
||||
*/
|
||||
public final Setting<Boolean> disableCompletionCheck = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Cached chunks (regardless of if they're in RAM or saved to disk) expire and are deleted after this number of seconds
|
||||
* -1 to disable
|
||||
@@ -719,11 +810,12 @@ public final class Settings {
|
||||
*/
|
||||
public final List<Setting<?>> allSettings;
|
||||
|
||||
public final Map<Setting<?>, Type> settingTypes;
|
||||
|
||||
public final class Setting<T> {
|
||||
public T value;
|
||||
public final T defaultValue;
|
||||
private String name;
|
||||
private final Class<T> klass;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Setting(T value) {
|
||||
@@ -732,7 +824,6 @@ public final class Settings {
|
||||
}
|
||||
this.value = value;
|
||||
this.defaultValue = value;
|
||||
this.klass = (Class<T>) value.getClass();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -750,7 +841,8 @@ public final class Settings {
|
||||
}
|
||||
|
||||
public Class<T> getValueClass() {
|
||||
return klass;
|
||||
// noinspection unchecked
|
||||
return (Class<T>) TypeUtils.resolveBaseClass(getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -764,14 +856,21 @@ public final class Settings {
|
||||
public void reset() {
|
||||
value = defaultValue;
|
||||
}
|
||||
|
||||
public final Type getType() {
|
||||
return settingTypes.get(this);
|
||||
}
|
||||
}
|
||||
|
||||
// here be dragons
|
||||
|
||||
Settings() {
|
||||
Field[] temp = getClass().getFields();
|
||||
HashMap<String, Setting<?>> tmpByName = new HashMap<>();
|
||||
|
||||
Map<String, Setting<?>> tmpByName = new HashMap<>();
|
||||
List<Setting<?>> tmpAll = new ArrayList<>();
|
||||
Map<Setting<?>, Type> tmpSettingTypes = new HashMap<>();
|
||||
|
||||
try {
|
||||
for (Field field : temp) {
|
||||
if (field.getType().equals(Setting.class)) {
|
||||
@@ -784,6 +883,7 @@ public final class Settings {
|
||||
}
|
||||
tmpByName.put(name, setting);
|
||||
tmpAll.add(setting);
|
||||
tmpSettingTypes.put(setting, ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]);
|
||||
}
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
@@ -791,6 +891,7 @@ public final class Settings {
|
||||
}
|
||||
byLowerName = Collections.unmodifiableMap(tmpByName);
|
||||
allSettings = Collections.unmodifiableList(tmpAll);
|
||||
settingTypes = Collections.unmodifiableMap(tmpSettingTypes);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -23,9 +23,8 @@ import baritone.api.event.listener.IGameEventListener;
|
||||
/**
|
||||
* A behavior is simply a type that is able to listen to events.
|
||||
*
|
||||
* @see IGameEventListener
|
||||
*
|
||||
* @author Brady
|
||||
* @see IGameEventListener
|
||||
* @since 9/23/2018
|
||||
*/
|
||||
public interface IBehavior extends AbstractGameEventListener {}
|
||||
|
||||
@@ -80,6 +80,13 @@ public interface IPathingBehavior extends IBehavior {
|
||||
*/
|
||||
boolean cancelEverything();
|
||||
|
||||
/**
|
||||
* PLEASE never call this
|
||||
* <p>
|
||||
* If cancelEverything was like "kill" this is "sudo kill -9". Or shutting off your computer.
|
||||
*/
|
||||
void forceCancel();
|
||||
|
||||
/**
|
||||
* Returns the current path, from the current path executor, if there is one.
|
||||
*
|
||||
|
||||
@@ -81,4 +81,6 @@ public interface ICachedWorld {
|
||||
* in a new thread by default.
|
||||
*/
|
||||
void save();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -15,9 +15,8 @@
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.cache;
|
||||
package baritone.api.cache;
|
||||
|
||||
import baritone.api.cache.IWaypoint;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.Date;
|
||||
@@ -47,7 +46,7 @@ public class Waypoint implements IWaypoint {
|
||||
* @param location The waypoint location
|
||||
* @param creationTimestamp When the waypoint was created
|
||||
*/
|
||||
Waypoint(String name, Tag tag, BlockPos location, long creationTimestamp) {
|
||||
public Waypoint(String name, Tag tag, BlockPos location, long creationTimestamp) {
|
||||
this.name = name;
|
||||
this.tag = tag;
|
||||
this.location = location;
|
||||
@@ -61,6 +61,6 @@ public class GoalNear implements Goal, IGoalRenderPos {
|
||||
", y=" + y +
|
||||
", z=" + z +
|
||||
", rangeSq=" + rangeSq +
|
||||
'}';
|
||||
"}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.pathing.goals;
|
||||
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
/**
|
||||
* Dig a tunnel in a certain direction, but if you have to deviate from the path, go back to where you started
|
||||
*/
|
||||
public class GoalStrictDirection implements Goal {
|
||||
public final int x;
|
||||
public final int y;
|
||||
public final int z;
|
||||
public final int dx;
|
||||
public final int dz;
|
||||
|
||||
public GoalStrictDirection(BlockPos origin, EnumFacing direction) {
|
||||
x = origin.getX();
|
||||
y = origin.getY();
|
||||
z = origin.getZ();
|
||||
dx = direction.getXOffset();
|
||||
dz = direction.getZOffset();
|
||||
if (dx == 0 && dz == 0) {
|
||||
throw new IllegalArgumentException(direction + "");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInGoal(int x, int y, int z) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double heuristic(int x, int y, int z) {
|
||||
int distanceFromStartInDesiredDirection = (x - this.x) * dx + (z - this.z) * dz;
|
||||
|
||||
int distanceFromStartInIncorrectDirection = Math.abs((x - this.x) * dz) + Math.abs((z - this.z) * dx);
|
||||
|
||||
int verticalDistanceFromStart = Math.abs(y - this.y);
|
||||
|
||||
// we want heuristic to decrease as desiredDirection increases
|
||||
double heuristic = -distanceFromStartInDesiredDirection * 100;
|
||||
|
||||
heuristic += distanceFromStartInIncorrectDirection * 1000;
|
||||
heuristic += verticalDistanceFromStart * 1000;
|
||||
return heuristic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GoalStrictDirection{" +
|
||||
"x=" + x +
|
||||
", y=" + y +
|
||||
", z=" + z +
|
||||
", dx=" + dx +
|
||||
", dz=" + dz +
|
||||
"}";
|
||||
}
|
||||
}
|
||||
@@ -31,17 +31,17 @@ public class GoalTwoBlocks implements Goal, IGoalRenderPos {
|
||||
/**
|
||||
* The X block position of this goal
|
||||
*/
|
||||
private final int x;
|
||||
protected final int x;
|
||||
|
||||
/**
|
||||
* The Y block position of this goal
|
||||
*/
|
||||
private final int y;
|
||||
protected final int y;
|
||||
|
||||
/**
|
||||
* The Z block position of this goal
|
||||
*/
|
||||
private final int z;
|
||||
protected final int z;
|
||||
|
||||
public GoalTwoBlocks(BlockPos pos) {
|
||||
this(pos.getX(), pos.getY(), pos.getZ());
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
package baritone.api.process;
|
||||
|
||||
import baritone.api.utils.ISchematic;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
|
||||
import java.io.File;
|
||||
@@ -46,4 +48,15 @@ public interface IBuilderProcess extends IBaritoneProcess {
|
||||
* @return Whether or not the schematic was able to load from file
|
||||
*/
|
||||
boolean build(String name, File schematic, Vec3i origin);
|
||||
|
||||
default boolean build(String schematicFile, BlockPos origin) {
|
||||
File file = new File(new File(Minecraft.getMinecraft().gameDir, "schematics"), schematicFile);
|
||||
return build(schematicFile, file, origin);
|
||||
}
|
||||
|
||||
void pause();
|
||||
|
||||
void resume();
|
||||
|
||||
void clearArea(BlockPos corner1, BlockPos corner2);
|
||||
}
|
||||
|
||||
26
src/api/java/baritone/api/process/IExploreProcess.java
Normal file
26
src/api/java/baritone/api/process/IExploreProcess.java
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.process;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public interface IExploreProcess extends IBaritoneProcess {
|
||||
void explore(int centerX, int centerZ);
|
||||
|
||||
void applyJsonFilter(Path path, boolean invert) throws Exception;
|
||||
}
|
||||
22
src/api/java/baritone/api/process/IFarmProcess.java
Normal file
22
src/api/java/baritone/api/process/IFarmProcess.java
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.process;
|
||||
|
||||
public interface IFarmProcess extends IBaritoneProcess {
|
||||
void farm();
|
||||
}
|
||||
@@ -25,4 +25,6 @@ import net.minecraft.block.Block;
|
||||
public interface IGetToBlockProcess extends IBaritoneProcess {
|
||||
|
||||
void getToBlock(Block block);
|
||||
|
||||
boolean blacklistClosest();
|
||||
}
|
||||
|
||||
@@ -51,5 +51,10 @@ public enum PathingCommandType {
|
||||
* <p>
|
||||
* Cancel the current path if the goals are not equal
|
||||
*/
|
||||
FORCE_REVALIDATE_GOAL_AND_PATH
|
||||
FORCE_REVALIDATE_GOAL_AND_PATH,
|
||||
|
||||
/**
|
||||
* Go and ask the next process what to do
|
||||
*/
|
||||
DEFER
|
||||
}
|
||||
|
||||
63
src/api/java/baritone/api/utils/BlockUtils.java
Normal file
63
src/api/java/baritone/api/utils/BlockUtils.java
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.utils;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class BlockUtils {
|
||||
private static transient Map<String, Block> resourceCache = new HashMap<>();
|
||||
|
||||
public static String blockToString(Block block) {
|
||||
ResourceLocation loc = Block.REGISTRY.getNameForObject(block);
|
||||
String name = loc.getPath(); // normally, only write the part after the minecraft:
|
||||
if (!loc.getNamespace().equals("minecraft")) {
|
||||
// Baritone is running on top of forge with mods installed, perhaps?
|
||||
name = loc.toString(); // include the namespace with the colon
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public static Block stringToBlockRequired(String name) {
|
||||
Block block = stringToBlockNullable(name);
|
||||
Objects.requireNonNull(block);
|
||||
return block;
|
||||
}
|
||||
|
||||
public static Block stringToBlockNullable(String name) {
|
||||
// do NOT just replace this with a computeWithAbsent, it isn't thread safe
|
||||
Block block = resourceCache.get(name); // map is never mutated in place so this is safe
|
||||
if (block != null) {
|
||||
return block;
|
||||
}
|
||||
if (resourceCache.containsKey(name)) {
|
||||
return null; // cached as null
|
||||
}
|
||||
block = Block.getBlockFromName(name.contains(":") ? name : "minecraft:" + name);
|
||||
Map<String, Block> copy = new HashMap<>(resourceCache); // read only copy is safe, wont throw concurrentmodification
|
||||
copy.put(name, block);
|
||||
resourceCache = copy;
|
||||
return block;
|
||||
}
|
||||
|
||||
private BlockUtils() {}
|
||||
}
|
||||
@@ -15,27 +15,21 @@
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.utils;
|
||||
package baritone.api.utils;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.Settings;
|
||||
import baritone.api.behavior.IPathingBehavior;
|
||||
import baritone.api.cache.IRememberedInventory;
|
||||
import baritone.api.cache.IWaypoint;
|
||||
import baritone.api.cache.Waypoint;
|
||||
import baritone.api.event.events.ChatEvent;
|
||||
import baritone.api.event.listener.AbstractGameEventListener;
|
||||
import baritone.api.pathing.goals.*;
|
||||
import baritone.api.pathing.movement.ActionCosts;
|
||||
import baritone.api.process.IBaritoneProcess;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.api.utils.SettingsUtil;
|
||||
import baritone.behavior.Behavior;
|
||||
import baritone.behavior.PathingBehavior;
|
||||
import baritone.cache.ChunkPacker;
|
||||
import baritone.cache.Waypoint;
|
||||
import baritone.pathing.movement.CalculationContext;
|
||||
import baritone.pathing.movement.Movement;
|
||||
import baritone.pathing.movement.Moves;
|
||||
import baritone.process.CustomGoalProcess;
|
||||
import baritone.utils.pathing.SegmentedCalculator;
|
||||
import baritone.api.process.ICustomGoalProcess;
|
||||
import baritone.api.process.IGetToBlockProcess;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ChunkProviderClient;
|
||||
@@ -45,11 +39,10 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
public class ExampleBaritoneControl implements Helper, AbstractGameEventListener {
|
||||
|
||||
private static final String HELP_MSG =
|
||||
"baritone - Output settings into chat\n" +
|
||||
@@ -83,21 +76,26 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
|
||||
private static final String COMMAND_PREFIX = "#";
|
||||
|
||||
public ExampleBaritoneControl(Baritone baritone) {
|
||||
super(baritone);
|
||||
public final IBaritone baritone;
|
||||
public final IPlayerContext ctx;
|
||||
|
||||
public ExampleBaritoneControl(IBaritone baritone) {
|
||||
this.baritone = baritone;
|
||||
this.ctx = baritone.getPlayerContext();
|
||||
baritone.getGameEventHandler().registerEventListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSendChatMessage(ChatEvent event) {
|
||||
String msg = event.getMessage();
|
||||
if (Baritone.settings().prefixControl.value && msg.startsWith(COMMAND_PREFIX)) {
|
||||
if (BaritoneAPI.getSettings().prefixControl.value && msg.startsWith(COMMAND_PREFIX)) {
|
||||
if (!runCommand(msg.substring(COMMAND_PREFIX.length()))) {
|
||||
logDirect("Invalid command");
|
||||
}
|
||||
event.cancel(); // always cancel if using prefixControl
|
||||
return;
|
||||
}
|
||||
if (!Baritone.settings().chatControl.value && !Baritone.settings().removePrefix.value) {
|
||||
if (!BaritoneAPI.getSettings().chatControl.value && !BaritoneAPI.getSettings().removePrefix.value) {
|
||||
return;
|
||||
}
|
||||
if (runCommand(msg)) {
|
||||
@@ -107,20 +105,20 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
|
||||
public boolean runCommand(String msg0) { // you may think this can be private, but impcat calls it from .b =)
|
||||
String msg = msg0.toLowerCase(Locale.US).trim(); // don't reassign the argument LOL
|
||||
PathingBehavior pathingBehavior = baritone.getPathingBehavior();
|
||||
CustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
|
||||
List<Settings.Setting<Boolean>> toggleable = Baritone.settings().getAllValuesByType(Boolean.class);
|
||||
IPathingBehavior pathingBehavior = baritone.getPathingBehavior();
|
||||
ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
|
||||
List<Settings.Setting<Boolean>> toggleable = BaritoneAPI.getSettings().getAllValuesByType(Boolean.class);
|
||||
for (Settings.Setting<Boolean> setting : toggleable) {
|
||||
if (msg.equalsIgnoreCase(setting.getName())) {
|
||||
setting.value ^= true;
|
||||
logDirect("Toggled " + setting.getName() + " to " + setting.value);
|
||||
SettingsUtil.save(Baritone.settings());
|
||||
SettingsUtil.save(BaritoneAPI.getSettings());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (msg.equals("baritone") || msg.equals("modifiedsettings") || msg.startsWith("settings m") || msg.equals("modified")) {
|
||||
logDirect("All settings that have been modified from their default values:");
|
||||
for (Settings.Setting<?> setting : SettingsUtil.modifiedSettings(Baritone.settings())) {
|
||||
for (Settings.Setting<?> setting : SettingsUtil.modifiedSettings(BaritoneAPI.getSettings())) {
|
||||
logDirect(setting.toString());
|
||||
}
|
||||
return true;
|
||||
@@ -130,15 +128,15 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
try {
|
||||
int page = Integer.parseInt(rest.trim());
|
||||
int min = page * 10;
|
||||
int max = Math.min(Baritone.settings().allSettings.size(), (page + 1) * 10);
|
||||
int max = Math.min(BaritoneAPI.getSettings().allSettings.size(), (page + 1) * 10);
|
||||
logDirect("Settings " + min + " to " + (max - 1) + ":");
|
||||
for (int i = min; i < max; i++) {
|
||||
logDirect(Baritone.settings().allSettings.get(i).toString());
|
||||
logDirect(BaritoneAPI.getSettings().allSettings.get(i).toString());
|
||||
}
|
||||
} catch (Exception ex) { // NumberFormatException | ArrayIndexOutOfBoundsException and probably some others I'm forgetting lol
|
||||
ex.printStackTrace();
|
||||
logDirect("All settings:");
|
||||
for (Settings.Setting<?> setting : Baritone.settings().allSettings) {
|
||||
for (Settings.Setting<?> setting : BaritoneAPI.getSettings().allSettings) {
|
||||
logDirect(setting.toString());
|
||||
}
|
||||
logDirect("To get one page of ten settings at a time, do settings <num>");
|
||||
@@ -154,26 +152,26 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
if (msg.contains(" ")) {
|
||||
String settingName = msg.substring(0, msg.indexOf(' '));
|
||||
String settingValue = msg.substring(msg.indexOf(' ') + 1);
|
||||
Settings.Setting setting = Baritone.settings().byLowerName.get(settingName);
|
||||
Settings.Setting setting = BaritoneAPI.getSettings().byLowerName.get(settingName);
|
||||
if (setting != null) {
|
||||
if (settingValue.equals("reset")) {
|
||||
logDirect("Resetting setting " + settingName + " to default value.");
|
||||
setting.reset();
|
||||
} else {
|
||||
try {
|
||||
SettingsUtil.parseAndApply(Baritone.settings(), settingName, settingValue);
|
||||
SettingsUtil.parseAndApply(BaritoneAPI.getSettings(), settingName, settingValue);
|
||||
} catch (Exception ex) {
|
||||
logDirect("Unable to parse setting");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
SettingsUtil.save(Baritone.settings());
|
||||
SettingsUtil.save(BaritoneAPI.getSettings());
|
||||
logDirect(setting.toString());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (Baritone.settings().byLowerName.containsKey(msg)) {
|
||||
Settings.Setting<?> setting = Baritone.settings().byLowerName.get(msg);
|
||||
if (BaritoneAPI.getSettings().byLowerName.containsKey(msg)) {
|
||||
Settings.Setting<?> setting = BaritoneAPI.getSettings().byLowerName.get(msg);
|
||||
logDirect(setting.toString());
|
||||
return true;
|
||||
}
|
||||
@@ -209,7 +207,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("fullpath")) {
|
||||
/*if (msg.equals("fullpath")) {
|
||||
if (pathingBehavior.getGoal() == null) {
|
||||
logDirect("No goal.");
|
||||
} else {
|
||||
@@ -225,7 +223,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}*/
|
||||
if (msg.equals("proc")) {
|
||||
Optional<IBaritoneProcess> proc = baritone.getPathingControlManager().mostRecentInControl();
|
||||
if (!proc.isPresent()) {
|
||||
@@ -283,7 +281,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("come")) {
|
||||
customGoalProcess.setGoalAndPath(new GoalBlock(new BlockPos(mc.getRenderViewEntity())));
|
||||
customGoalProcess.setGoalAndPath(new GoalBlock(new BlockPos(Helper.mc.getRenderViewEntity())));
|
||||
logDirect("Coming");
|
||||
return true;
|
||||
}
|
||||
@@ -353,21 +351,42 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
baritone.getBuilderProcess().clearArea(corner1, corner2);
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("resume")) {
|
||||
baritone.getBuilderProcess().resume();
|
||||
logDirect("resumed");
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("pause")) {
|
||||
baritone.getBuilderProcess().pause();
|
||||
logDirect("paused");
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("reset")) {
|
||||
for (Settings.Setting setting : Baritone.settings().allSettings) {
|
||||
for (Settings.Setting setting : BaritoneAPI.getSettings().allSettings) {
|
||||
setting.reset();
|
||||
}
|
||||
SettingsUtil.save(Baritone.settings());
|
||||
SettingsUtil.save(BaritoneAPI.getSettings());
|
||||
logDirect("Baritone settings reset");
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("tunnel")) {
|
||||
customGoalProcess.setGoalAndPath(new GoalStrictDirection(ctx.playerFeet(), ctx.player().getHorizontalFacing()));
|
||||
logDirect("tunneling");
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("render")) {
|
||||
BetterBlockPos pf = ctx.playerFeet();
|
||||
Minecraft.getMinecraft().renderGlobal.markBlockRangeForRenderUpdate(pf.x - 500, pf.y - 500, pf.z - 500, pf.x + 500, pf.y + 500, pf.z + 500);
|
||||
logDirect("okay");
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("echest")) {
|
||||
if (msg.equals("farm")) {
|
||||
baritone.getFarmProcess().farm();
|
||||
logDirect("farming");
|
||||
return true;
|
||||
}
|
||||
// this literally doesn't work, memory is disabled lol
|
||||
/*if (msg.equals("echest")) {
|
||||
Optional<List<ItemStack>> contents = baritone.getMemoryBehavior().echest();
|
||||
if (contents.isPresent()) {
|
||||
logDirect("echest contents:");
|
||||
@@ -376,18 +395,8 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
logDirect("echest contents unknown");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}*/
|
||||
if (msg.equals("chests")) {
|
||||
System.out.println(baritone.getWorldProvider());
|
||||
System.out.println(baritone.getWorldProvider().getCurrentWorld());
|
||||
|
||||
System.out.println(baritone.getWorldProvider().getCurrentWorld().getContainerMemory());
|
||||
|
||||
System.out.println(baritone.getWorldProvider().getCurrentWorld().getContainerMemory().getRememberedInventories());
|
||||
|
||||
System.out.println(baritone.getWorldProvider().getCurrentWorld().getContainerMemory().getRememberedInventories().entrySet());
|
||||
|
||||
System.out.println(baritone.getWorldProvider().getCurrentWorld().getContainerMemory().getRememberedInventories().entrySet());
|
||||
for (Map.Entry<BlockPos, IRememberedInventory> entry : baritone.getWorldProvider().getCurrentWorld().getContainerMemory().getRememberedInventories().entrySet()) {
|
||||
logDirect(entry.getKey() + "");
|
||||
log(entry.getValue().getContents());
|
||||
@@ -421,6 +430,29 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
logDirect("Following " + toFollow.get());
|
||||
return true;
|
||||
}
|
||||
if (msg.startsWith("explorefilter")) {
|
||||
// explorefilter blah.json
|
||||
// means that entries in blah.json are already explored
|
||||
// explorefilter blah.json invert
|
||||
// means that entries in blah.json are NOT already explored
|
||||
String path = msg.substring("explorefilter".length()).trim();
|
||||
String[] parts = path.split(" ");
|
||||
Path path1 = Minecraft.getMinecraft().gameDir.toPath().resolve(parts[0]);
|
||||
boolean invert = parts.length > 1;
|
||||
try {
|
||||
baritone.getExploreProcess().applyJsonFilter(path1, invert);
|
||||
logDirect("Loaded filter. Inverted: " + invert);
|
||||
if (invert) {
|
||||
logDirect("Chunks on this list will be treated as possibly unexplored, all others will be treated as certainly explored");
|
||||
} else {
|
||||
logDirect("Chunks on this list will be treated as certainly explored, all others will be treated as possibly unexplored");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
logDirect("Unable to load " + path1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("reloadall")) {
|
||||
baritone.getWorldProvider().getCurrentWorld().getCachedWorld().reloadAllFromDisk();
|
||||
logDirect("ok");
|
||||
@@ -446,14 +478,27 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
logDirect("Exploring from " + centerX + "," + centerZ);
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("blacklist")) {
|
||||
IGetToBlockProcess proc = baritone.getGetToBlockProcess();
|
||||
if (!proc.isActive()) {
|
||||
logDirect("GetToBlockProcess is not currently active");
|
||||
return true;
|
||||
}
|
||||
if (proc.blacklistClosest()) {
|
||||
logDirect("Blacklisted closest instances");
|
||||
} else {
|
||||
logDirect("No known locations, unable to blacklist");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (msg.startsWith("find")) {
|
||||
String blockType = msg.substring(4).trim();
|
||||
ArrayList<BlockPos> locs = baritone.getWorldProvider().getCurrentWorld().getCachedWorld().getLocationsOf(blockType, 1, ctx.playerFeet().getX(), ctx.playerFeet().getZ(), 4);
|
||||
logDirect("Have " + locs.size() + " locations");
|
||||
for (BlockPos pos : locs) {
|
||||
Block actually = BlockStateInterface.get(ctx, pos).getBlock();
|
||||
if (!ChunkPacker.blockToString(actually).equalsIgnoreCase(blockType)) {
|
||||
System.out.println("Was looking for " + blockType + " but actually found " + actually + " " + ChunkPacker.blockToString(actually));
|
||||
Block actually = ctx.world().getBlockState(pos).getBlock();
|
||||
if (!BlockUtils.blockToString(actually).equalsIgnoreCase(blockType)) {
|
||||
logDebug("Was looking for " + blockType + " but actually found " + actually + " " + BlockUtils.blockToString(actually));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -462,13 +507,13 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
String[] blockTypes = msg.substring(4).trim().split(" ");
|
||||
try {
|
||||
int quantity = Integer.parseInt(blockTypes[1]);
|
||||
Block block = ChunkPacker.stringToBlockRequired(blockTypes[0]);
|
||||
Block block = BlockUtils.stringToBlockRequired(blockTypes[0]);
|
||||
baritone.getMineProcess().mine(quantity, block);
|
||||
logDirect("Will mine " + quantity + " " + blockTypes[0]);
|
||||
return true;
|
||||
} catch (NumberFormatException | ArrayIndexOutOfBoundsException | NullPointerException ex) {}
|
||||
for (String s : blockTypes) {
|
||||
if (ChunkPacker.stringToBlockNullable(s) == null) {
|
||||
if (BlockUtils.stringToBlockNullable(s) == null) {
|
||||
logDirect(s + " isn't a valid block name");
|
||||
return true;
|
||||
}
|
||||
@@ -479,12 +524,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("click")) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
mc.addScheduledTask(() -> mc.displayGuiScreen(new GuiClick()));
|
||||
} catch (Exception ignored) {}
|
||||
}).start();
|
||||
baritone.openClick();
|
||||
logDirect("aight dude");
|
||||
return true;
|
||||
}
|
||||
@@ -504,9 +544,9 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
// for example, "show deaths"
|
||||
waypointType = waypointType.substring(0, waypointType.length() - 1);
|
||||
}
|
||||
Waypoint.Tag tag = Waypoint.Tag.fromString(waypointType);
|
||||
IWaypoint.Tag tag = IWaypoint.Tag.fromString(waypointType);
|
||||
if (tag == null) {
|
||||
logDirect("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
|
||||
logDirect("Not a valid tag. Tags are: " + Arrays.asList(IWaypoint.Tag.values()).toString().toLowerCase());
|
||||
return true;
|
||||
}
|
||||
Set<IWaypoint> waypoints = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getByTag(tag);
|
||||
@@ -537,21 +577,21 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
}
|
||||
name = parts[0];
|
||||
}
|
||||
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint(name, Waypoint.Tag.USER, pos));
|
||||
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint(name, IWaypoint.Tag.USER, pos));
|
||||
logDirect("Saved user defined position " + pos + " under name '" + name + "'. Say 'goto " + name + "' to set goal, say 'list user' to list custom waypoints.");
|
||||
return true;
|
||||
}
|
||||
if (msg.startsWith("goto")) {
|
||||
String waypointType = msg.substring(4).trim();
|
||||
if (waypointType.endsWith("s") && Waypoint.Tag.fromString(waypointType.substring(0, waypointType.length() - 1)) != null) {
|
||||
if (waypointType.endsWith("s") && IWaypoint.Tag.fromString(waypointType.substring(0, waypointType.length() - 1)) != null) {
|
||||
// for example, "show deaths"
|
||||
waypointType = waypointType.substring(0, waypointType.length() - 1);
|
||||
}
|
||||
Waypoint.Tag tag = Waypoint.Tag.fromString(waypointType);
|
||||
IWaypoint.Tag tag = IWaypoint.Tag.fromString(waypointType);
|
||||
IWaypoint waypoint;
|
||||
if (tag == null) {
|
||||
String mining = waypointType;
|
||||
Block block = ChunkPacker.stringToBlockNullable(mining);
|
||||
Block block = BlockUtils.stringToBlockNullable(mining);
|
||||
//logDirect("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
|
||||
if (block == null) {
|
||||
waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getAllWaypoints().stream().filter(w -> w.getName().equalsIgnoreCase(mining)).max(Comparator.comparingLong(IWaypoint::getCreationTimestamp)).orElse(null);
|
||||
@@ -574,12 +614,12 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Goal goal = waypoint.getTag() == Waypoint.Tag.BED ? new GoalGetToBlock(waypoint.getLocation()) : new GoalBlock(waypoint.getLocation());
|
||||
Goal goal = waypoint.getTag() == IWaypoint.Tag.BED ? new GoalGetToBlock(waypoint.getLocation()) : new GoalBlock(waypoint.getLocation());
|
||||
customGoalProcess.setGoalAndPath(goal);
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("spawn") || msg.equals("bed")) {
|
||||
IWaypoint waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getMostRecentByTag(Waypoint.Tag.BED);
|
||||
IWaypoint waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getMostRecentByTag(IWaypoint.Tag.BED);
|
||||
if (waypoint == null) {
|
||||
BlockPos spawnPoint = ctx.player().getBedLocation();
|
||||
// for some reason the default spawnpoint is underground sometimes
|
||||
@@ -594,12 +634,12 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("sethome")) {
|
||||
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("", Waypoint.Tag.HOME, ctx.playerFeet()));
|
||||
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("", IWaypoint.Tag.HOME, ctx.playerFeet()));
|
||||
logDirect("Saved. Say home to set goal.");
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("home")) {
|
||||
IWaypoint waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getMostRecentByTag(Waypoint.Tag.HOME);
|
||||
IWaypoint waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getMostRecentByTag(IWaypoint.Tag.HOME);
|
||||
if (waypoint == null) {
|
||||
logDirect("home not saved");
|
||||
} else {
|
||||
@@ -609,7 +649,8 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("costs")) {
|
||||
// this is completely impossible from api
|
||||
/*if (msg.equals("costs")) {
|
||||
List<Movement> moves = Stream.of(Moves.values()).map(x -> x.apply0(new CalculationContext(baritone), ctx.playerFeet())).collect(Collectors.toCollection(ArrayList::new));
|
||||
while (moves.contains(null)) {
|
||||
moves.remove(null);
|
||||
@@ -625,7 +666,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
logDirect(parts[parts.length - 1] + " " + move.getDest().getX() + "," + move.getDest().getY() + "," + move.getDest().getZ() + " " + strCost);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}*/
|
||||
if (msg.equals("damn")) {
|
||||
logDirect("daniel");
|
||||
}
|
||||
@@ -15,9 +15,9 @@
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.utils;
|
||||
package baritone.api.utils;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextComponentString;
|
||||
@@ -50,7 +50,7 @@ public interface Helper {
|
||||
* @param message The message to display in chat
|
||||
*/
|
||||
default void logDebug(String message) {
|
||||
if (!Baritone.settings().chatDebug.value) {
|
||||
if (!BaritoneAPI.getSettings().chatDebug.value) {
|
||||
//System.out.println("Suppressed debug message:");
|
||||
//System.out.println(message);
|
||||
return;
|
||||
@@ -67,6 +67,6 @@ public interface Helper {
|
||||
ITextComponent component = MESSAGE_PREFIX.createCopy();
|
||||
component.getStyle().setColor(TextFormatting.GRAY);
|
||||
component.appendSibling(new TextComponentString(" " + message));
|
||||
Minecraft.getMinecraft().addScheduledTask(() -> Baritone.settings().logger.value.accept(component));
|
||||
Minecraft.getMinecraft().addScheduledTask(() -> BaritoneAPI.getSettings().logger.value.accept(component));
|
||||
}
|
||||
}
|
||||
@@ -71,20 +71,26 @@ public interface IPlayerContext {
|
||||
* @return The position of the highlighted block
|
||||
*/
|
||||
default Optional<BlockPos> getSelectedBlock() {
|
||||
if (objectMouseOver() != null && objectMouseOver().typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||
return Optional.of(objectMouseOver().getBlockPos());
|
||||
RayTraceResult result = objectMouseOver();
|
||||
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||
return Optional.of(result.getBlockPos());
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
default boolean isLookingAt(BlockPos pos) {
|
||||
return getSelectedBlock().equals(Optional.of(pos));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entity that the crosshair is currently placed over. Updated once per tick.
|
||||
*
|
||||
* @return The entity
|
||||
*/
|
||||
default Optional<Entity> getSelectedEntity() {
|
||||
if (objectMouseOver() != null && objectMouseOver().typeOfHit == RayTraceResult.Type.ENTITY) {
|
||||
return Optional.of(objectMouseOver().entityHit);
|
||||
RayTraceResult result = objectMouseOver();
|
||||
if (result != null && result.typeOfHit == RayTraceResult.Type.ENTITY) {
|
||||
return Optional.of(result.entityHit);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package baritone.api.utils;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
/**
|
||||
* Basic representation of a schematic. Provides the dimensions and
|
||||
@@ -44,6 +45,19 @@ public interface ISchematic {
|
||||
return x >= 0 && x < widthX() && y >= 0 && y < heightY() && z >= 0 && z < lengthZ();
|
||||
}
|
||||
|
||||
default int size(EnumFacing.Axis axis) {
|
||||
switch (axis) {
|
||||
case X:
|
||||
return widthX();
|
||||
case Y:
|
||||
return heightY();
|
||||
case Z:
|
||||
return lengthZ();
|
||||
default:
|
||||
throw new UnsupportedOperationException(axis + "");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the desired block state at a given (X, Y, Z) position relative to the origin (0, 0, 0).
|
||||
*
|
||||
|
||||
31
src/api/java/baritone/api/utils/MyChunkPos.java
Normal file
31
src/api/java/baritone/api/utils/MyChunkPos.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.utils;
|
||||
|
||||
/**
|
||||
* Need a non obfed chunkpos that we can load using GSON
|
||||
*/
|
||||
public class MyChunkPos {
|
||||
public int x;
|
||||
public int z;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return x + ", " + z;
|
||||
}
|
||||
}
|
||||
@@ -18,32 +18,33 @@
|
||||
package baritone.api.utils;
|
||||
|
||||
import baritone.api.Settings;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static net.minecraft.client.Minecraft.getMinecraft;
|
||||
|
||||
public class SettingsUtil {
|
||||
|
||||
private static final Path SETTINGS_PATH = getMinecraft().gameDir.toPath().resolve("baritone").resolve("settings.txt");
|
||||
private static final Pattern SETTING_PATTERN = Pattern.compile("^(?<setting>[^ ]+) +(?<value>[^ ]+)"); // 2 words separated by spaces
|
||||
|
||||
private static final Map<Class<?>, SettingsIO> map;
|
||||
private static final Pattern SETTING_PATTERN = Pattern.compile("^(?<setting>[^ ]+) +(?<value>.+)"); // key and value split by the first space
|
||||
|
||||
private static boolean isComment(String line) {
|
||||
return line.startsWith("#") || line.startsWith("//");
|
||||
@@ -118,11 +119,11 @@ public class SettingsUtil {
|
||||
if (setting.getName().equals("logger")) {
|
||||
return "logger";
|
||||
}
|
||||
SettingsIO io = map.get(setting.getValueClass());
|
||||
Parser io = Parser.getParser(setting.getType());
|
||||
if (io == null) {
|
||||
throw new IllegalStateException("Missing " + setting.getValueClass() + " " + setting.getName());
|
||||
}
|
||||
return setting.getName() + " " + io.toString.apply(setting.value);
|
||||
return setting.getName() + " " + io.toString(new ParserContext(setting), setting.value);
|
||||
}
|
||||
|
||||
public static void parseAndApply(Settings settings, String settingName, String settingValue) throws IllegalStateException, NumberFormatException {
|
||||
@@ -131,45 +132,125 @@ public class SettingsUtil {
|
||||
throw new IllegalStateException("No setting by that name");
|
||||
}
|
||||
Class intendedType = setting.getValueClass();
|
||||
SettingsIO ioMethod = map.get(intendedType);
|
||||
Object parsed = ioMethod.parser.apply(settingValue);
|
||||
ISettingParser ioMethod = Parser.getParser(setting.getType());
|
||||
Object parsed = ioMethod.parse(new ParserContext(setting), settingValue);
|
||||
if (!intendedType.isInstance(parsed)) {
|
||||
throw new IllegalStateException(ioMethod + " parser returned incorrect type, expected " + intendedType + " got " + parsed + " which is " + parsed.getClass());
|
||||
}
|
||||
setting.value = parsed;
|
||||
}
|
||||
|
||||
private enum SettingsIO {
|
||||
private interface ISettingParser<T> {
|
||||
|
||||
T parse(ParserContext context, String raw);
|
||||
|
||||
String toString(ParserContext context, T value);
|
||||
|
||||
boolean accepts(Type type);
|
||||
}
|
||||
|
||||
private static class ParserContext {
|
||||
|
||||
private final Settings.Setting<?> setting;
|
||||
|
||||
public ParserContext(Settings.Setting<?> setting) {
|
||||
this.setting = setting;
|
||||
}
|
||||
|
||||
final Settings.Setting<?> getSetting() {
|
||||
return this.setting;
|
||||
}
|
||||
}
|
||||
|
||||
private enum Parser implements ISettingParser {
|
||||
|
||||
DOUBLE(Double.class, Double::parseDouble),
|
||||
BOOLEAN(Boolean.class, Boolean::parseBoolean),
|
||||
INTEGER(Integer.class, Integer::parseInt),
|
||||
FLOAT(Float.class, Float::parseFloat),
|
||||
LONG(Long.class, Long::parseLong),
|
||||
ENUMFACING(EnumFacing.class, EnumFacing::byName),
|
||||
COLOR(
|
||||
Color.class,
|
||||
str -> new Color(Integer.parseInt(str.split(",")[0]), Integer.parseInt(str.split(",")[1]), Integer.parseInt(str.split(",")[2])),
|
||||
color -> color.getRed() + "," + color.getGreen() + "," + color.getBlue()
|
||||
),
|
||||
BLOCK(
|
||||
Block.class,
|
||||
str -> BlockUtils.stringToBlockRequired(str.trim()),
|
||||
BlockUtils::blockToString
|
||||
),
|
||||
ITEM(
|
||||
Item.class,
|
||||
str -> Item.getByNameOrId(str.trim()),
|
||||
item -> Item.REGISTRY.getNameForObject(item).toString()
|
||||
),
|
||||
LIST() {
|
||||
@Override
|
||||
public Object parse(ParserContext context, String raw) {
|
||||
Type type = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
|
||||
Parser parser = Parser.getParser(type);
|
||||
|
||||
ITEM_LIST(ArrayList.class, str -> Stream.of(str.split(",")).map(Item::getByNameOrId).collect(Collectors.toCollection(ArrayList::new)), list -> ((ArrayList<Item>) list).stream().map(Item.REGISTRY::getNameForObject).map(ResourceLocation::toString).collect(Collectors.joining(","))),
|
||||
COLOR(Color.class, str -> new Color(Integer.parseInt(str.split(",")[0]), Integer.parseInt(str.split(",")[1]), Integer.parseInt(str.split(",")[2])), color -> color.getRed() + "," + color.getGreen() + "," + color.getBlue());
|
||||
return Arrays.stream(raw.split(","))
|
||||
.map(s -> parser.parse(context, s))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(ParserContext context, Object value) {
|
||||
Type type = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
|
||||
Parser parser = Parser.getParser(type);
|
||||
|
||||
Class<?> klass;
|
||||
Function<String, Object> parser;
|
||||
Function<Object, String> toString;
|
||||
return ((List<?>) value).stream()
|
||||
.map(o -> parser.toString(context, o))
|
||||
.collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
<T> SettingsIO(Class<T> klass, Function<String, T> parser) {
|
||||
@Override
|
||||
public boolean accepts(Type type) {
|
||||
return List.class.isAssignableFrom(TypeUtils.resolveBaseClass(type));
|
||||
}
|
||||
};
|
||||
|
||||
private final Class<?> klass;
|
||||
private final Function<String, Object> parser;
|
||||
private final Function<Object, String> toString;
|
||||
|
||||
Parser() {
|
||||
this.klass = null;
|
||||
this.parser = null;
|
||||
this.toString = null;
|
||||
}
|
||||
|
||||
<T> Parser(Class<T> klass, Function<String, T> parser) {
|
||||
this(klass, parser, Object::toString);
|
||||
}
|
||||
|
||||
<T> SettingsIO(Class<T> klass, Function<String, T> parser, Function<T, String> toString) {
|
||||
<T> Parser(Class<T> klass, Function<String, T> parser, Function<T, String> toString) {
|
||||
this.klass = klass;
|
||||
this.parser = parser::apply;
|
||||
this.toString = x -> toString.apply((T) x);
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
HashMap<Class<?>, SettingsIO> tempMap = new HashMap<>();
|
||||
for (SettingsIO type : SettingsIO.values()) {
|
||||
tempMap.put(type.klass, type);
|
||||
@Override
|
||||
public Object parse(ParserContext context, String raw) {
|
||||
return this.parser.apply(raw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(ParserContext context, Object value) {
|
||||
return this.toString.apply(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accepts(Type type) {
|
||||
return type instanceof Class && this.klass.isAssignableFrom((Class) type);
|
||||
}
|
||||
|
||||
public static Parser getParser(Type type) {
|
||||
return Arrays.stream(values())
|
||||
.filter(parser -> parser.accepts(type))
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
map = Collections.unmodifiableMap(tempMap);
|
||||
}
|
||||
}
|
||||
|
||||
44
src/api/java/baritone/api/utils/TypeUtils.java
Normal file
44
src/api/java/baritone/api/utils/TypeUtils.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.utils;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 4/20/2019
|
||||
*/
|
||||
public final class TypeUtils {
|
||||
|
||||
private TypeUtils() {}
|
||||
|
||||
/**
|
||||
* Resolves the "base type" for the specified type. For example, if the specified
|
||||
* type is {@code List<String>}, then {@code List.class} will be returned. If the
|
||||
* specified type is already a class, then it is directly returned.
|
||||
*
|
||||
* @param type The type to resolve
|
||||
* @return The base class
|
||||
*/
|
||||
public static Class<?> resolveBaseClass(Type type) {
|
||||
return type instanceof Class ? (Class<?>) type
|
||||
: type instanceof ParameterizedType ? (Class<?>) ((ParameterizedType) type).getRawType()
|
||||
: null;
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,8 @@ import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.Settings;
|
||||
import baritone.api.event.listener.IEventBus;
|
||||
import baritone.api.utils.ExampleBaritoneControl;
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
import baritone.behavior.*;
|
||||
import baritone.cache.WorldProvider;
|
||||
@@ -33,8 +35,6 @@ import net.minecraft.client.Minecraft;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
@@ -67,7 +67,6 @@ public class Baritone implements IBaritone {
|
||||
|
||||
private GameEventHandler gameEventHandler;
|
||||
|
||||
private List<Behavior> behaviors;
|
||||
private PathingBehavior pathingBehavior;
|
||||
private LookBehavior lookBehavior;
|
||||
private MemoryBehavior memoryBehavior;
|
||||
@@ -80,6 +79,8 @@ public class Baritone implements IBaritone {
|
||||
private CustomGoalProcess customGoalProcess;
|
||||
private BuilderProcess builderProcess;
|
||||
private ExploreProcess exploreProcess;
|
||||
private BackfillProcess backfillProcess;
|
||||
private FarmProcess farmProcess;
|
||||
|
||||
private PathingControlManager pathingControlManager;
|
||||
|
||||
@@ -101,7 +102,6 @@ public class Baritone implements IBaritone {
|
||||
// Define this before behaviors try and get it, or else it will be null and the builds will fail!
|
||||
this.playerContext = PrimaryPlayerContext.INSTANCE;
|
||||
|
||||
this.behaviors = new ArrayList<>();
|
||||
{
|
||||
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
|
||||
pathingBehavior = new PathingBehavior(this);
|
||||
@@ -120,6 +120,8 @@ public class Baritone implements IBaritone {
|
||||
getToBlockProcess = new GetToBlockProcess(this);
|
||||
builderProcess = new BuilderProcess(this);
|
||||
exploreProcess = new ExploreProcess(this);
|
||||
backfillProcess = new BackfillProcess(this);
|
||||
farmProcess = new FarmProcess(this);
|
||||
}
|
||||
|
||||
this.worldProvider = new WorldProvider();
|
||||
@@ -136,12 +138,7 @@ public class Baritone implements IBaritone {
|
||||
return this.pathingControlManager;
|
||||
}
|
||||
|
||||
public List<Behavior> getBehaviors() {
|
||||
return this.behaviors;
|
||||
}
|
||||
|
||||
public void registerBehavior(Behavior behavior) {
|
||||
this.behaviors.add(behavior);
|
||||
this.gameEventHandler.registerEventListener(behavior);
|
||||
}
|
||||
|
||||
@@ -197,6 +194,10 @@ public class Baritone implements IBaritone {
|
||||
return this.mineProcess;
|
||||
}
|
||||
|
||||
public FarmProcess getFarmProcess() {
|
||||
return this.farmProcess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PathingBehavior getPathingBehavior() {
|
||||
return this.pathingBehavior;
|
||||
@@ -212,6 +213,16 @@ public class Baritone implements IBaritone {
|
||||
return this.gameEventHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openClick() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
Helper.mc.addScheduledTask(() -> Helper.mc.displayGuiScreen(new GuiClick()));
|
||||
} catch (Exception ignored) {}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public static Settings settings() {
|
||||
return BaritoneAPI.getSettings();
|
||||
}
|
||||
|
||||
@@ -123,27 +123,27 @@ public class InventoryBehavior extends Behavior {
|
||||
|
||||
public boolean hasGenericThrowaway() {
|
||||
for (Item item : Baritone.settings().acceptableThrowawayItems.value) {
|
||||
if (throwaway(false, item::equals)) {
|
||||
if (throwaway(false, stack -> item.equals(stack.getItem()))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean selectThrowawayForLocation(int x, int y, int z) {
|
||||
public boolean selectThrowawayForLocation(boolean select, int x, int y, int z) {
|
||||
IBlockState maybe = baritone.getBuilderProcess().placeAt(x, y, z);
|
||||
if (maybe != null && throwaway(true, item -> item instanceof ItemBlock && ((ItemBlock) item).getBlock().equals(maybe.getBlock()))) {
|
||||
if (maybe != null && throwaway(select, stack -> stack.getItem() instanceof ItemBlock && ((ItemBlock) stack.getItem()).getBlock().equals(maybe.getBlock()))) {
|
||||
return true; // gotem
|
||||
}
|
||||
for (Item item : Baritone.settings().acceptableThrowawayItems.value) {
|
||||
if (throwaway(true, item::equals)) {
|
||||
if (throwaway(select, stack -> item.equals(stack.getItem()))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean throwaway(boolean select, Predicate<? super Item> desired) {
|
||||
public boolean throwaway(boolean select, Predicate<? super ItemStack> desired) {
|
||||
EntityPlayerSP p = ctx.player();
|
||||
NonNullList<ItemStack> inv = p.inventory.mainInventory;
|
||||
for (byte i = 0; i < 9; i++) {
|
||||
@@ -153,14 +153,14 @@ public class InventoryBehavior extends Behavior {
|
||||
// and then it's called during execution
|
||||
// since this function is never called during cost calculation, we don't need to migrate
|
||||
// acceptableThrowawayItems to the CalculationContext
|
||||
if (desired.test(item.getItem())) {
|
||||
if (desired.test(item)) {
|
||||
if (select) {
|
||||
p.inventory.currentItem = i;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (desired.test(p.inventory.offHandInventory.get(0).getItem())) {
|
||||
if (desired.test(p.inventory.offHandInventory.get(0))) {
|
||||
// main hand takes precedence over off hand
|
||||
// that means that if we have block A selected in main hand and block B in off hand, right clicking places block B
|
||||
// we've already checked above ^ and the main hand can't possible have an acceptablethrowawayitem
|
||||
|
||||
@@ -72,8 +72,8 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
|
||||
float oldPitch = ctx.player().rotationPitch;
|
||||
float desiredPitch = this.target.getPitch();
|
||||
ctx.player().rotationPitch = desiredPitch;
|
||||
if (desiredPitch == oldPitch) {
|
||||
//nudgeToLevel();
|
||||
if (desiredPitch == oldPitch && !Baritone.settings().freeLook.value) {
|
||||
nudgeToLevel();
|
||||
}
|
||||
this.target = null;
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
package baritone.behavior;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.cache.Waypoint;
|
||||
import baritone.api.event.events.BlockInteractEvent;
|
||||
import baritone.api.event.events.PacketEvent;
|
||||
import baritone.api.event.events.PlayerUpdateEvent;
|
||||
import baritone.api.event.events.TickEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import baritone.cache.ContainerMemory;
|
||||
import baritone.cache.Waypoint;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockBed;
|
||||
|
||||
@@ -25,6 +25,7 @@ import baritone.api.pathing.goals.Goal;
|
||||
import baritone.api.pathing.goals.GoalXZ;
|
||||
import baritone.api.process.PathingCommand;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.api.utils.PathCalculationResult;
|
||||
import baritone.api.utils.interfaces.IGoalRenderPos;
|
||||
import baritone.pathing.calc.AStarPathFinder;
|
||||
@@ -32,7 +33,6 @@ import baritone.pathing.calc.AbstractNodeCostSearch;
|
||||
import baritone.pathing.movement.CalculationContext;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.pathing.path.PathExecutor;
|
||||
import baritone.utils.Helper;
|
||||
import baritone.utils.PathRenderer;
|
||||
import baritone.utils.PathingCommandContext;
|
||||
import baritone.utils.pathing.Favoring;
|
||||
@@ -350,7 +350,8 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
}
|
||||
}
|
||||
|
||||
public void forceCancel() { // NOT exposed on public api
|
||||
@Override
|
||||
public void forceCancel() { // exposed on public api because :sob:
|
||||
cancelEverything();
|
||||
secretInternalSegmentCancel();
|
||||
synchronized (pathCalcLock) {
|
||||
@@ -358,11 +359,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
}
|
||||
}
|
||||
|
||||
public void secretCursedFunctionDoNotCall(IPath path) {
|
||||
/*public void secretCursedFunctionDoNotCall(IPath path) {
|
||||
synchronized (pathPlanLock) {
|
||||
current = new PathExecutor(this, path);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
public CalculationContext secretInternalGetCalculationContext() {
|
||||
return context;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package baritone.cache;
|
||||
|
||||
import baritone.api.utils.BlockUtils;
|
||||
import baritone.utils.pathing.PathingBlockType;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import net.minecraft.block.Block;
|
||||
@@ -177,7 +178,7 @@ public final class CachedChunk {
|
||||
if (special != null) {
|
||||
String str = special.get(index);
|
||||
if (str != null) {
|
||||
return ChunkPacker.stringToBlockRequired(str).getDefaultState();
|
||||
return BlockUtils.stringToBlockRequired(str).getDefaultState();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package baritone.cache;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.cache.ICachedRegion;
|
||||
import baritone.api.utils.BlockUtils;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
@@ -149,7 +150,7 @@ public final class CachedRegion implements ICachedRegion {
|
||||
for (int z = 0; z < 32; z++) {
|
||||
if (chunks[x][z] != null) {
|
||||
for (int i = 0; i < 256; i++) {
|
||||
out.writeUTF(ChunkPacker.blockToString(chunks[x][z].getOverview()[i].getBlock()));
|
||||
out.writeUTF(BlockUtils.blockToString(chunks[x][z].getOverview()[i].getBlock()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -240,7 +241,7 @@ public final class CachedRegion implements ICachedRegion {
|
||||
for (int z = 0; z < 32; z++) {
|
||||
if (present[x][z]) {
|
||||
for (int i = 0; i < 256; i++) {
|
||||
overview[x][z][i] = ChunkPacker.stringToBlockRequired(in.readUTF()).getDefaultState();
|
||||
overview[x][z][i] = BlockUtils.stringToBlockRequired(in.readUTF()).getDefaultState();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -255,7 +256,7 @@ public final class CachedRegion implements ICachedRegion {
|
||||
int numSpecialBlockTypes = in.readShort() & 0xffff;
|
||||
for (int i = 0; i < numSpecialBlockTypes; i++) {
|
||||
String blockName = in.readUTF();
|
||||
ChunkPacker.stringToBlockRequired(blockName);
|
||||
BlockUtils.stringToBlockRequired(blockName);
|
||||
List<BlockPos> locs = new ArrayList<>();
|
||||
location[x][z].put(blockName, locs);
|
||||
int numLocations = in.readShort() & 0xffff;
|
||||
|
||||
@@ -22,7 +22,7 @@ import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.cache.ICachedWorld;
|
||||
import baritone.api.cache.IWorldData;
|
||||
import baritone.utils.Helper;
|
||||
import baritone.api.utils.Helper;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@@ -180,8 +180,8 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
||||
if (region == null) {
|
||||
continue;
|
||||
}
|
||||
int distX = (region.getX() << 9 + 256) - pruneCenter.getX();
|
||||
int distZ = (region.getZ() << 9 + 256) - pruneCenter.getZ();
|
||||
int distX = ((region.getX() << 9) + 256) - pruneCenter.getX();
|
||||
int distZ = ((region.getZ() << 9) + 256) - pruneCenter.getZ();
|
||||
double dist = Math.sqrt(distX * distX + distZ * distZ);
|
||||
if (dist > 1024) {
|
||||
logDebug("Deleting cached region " + region.getX() + "," + region.getZ() + " from ram");
|
||||
@@ -216,7 +216,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
||||
if (mostRecentlyModified == null) {
|
||||
return new BlockPos(0, 0, 0);
|
||||
}
|
||||
return new BlockPos(mostRecentlyModified.x << 4 + 8, 0, mostRecentlyModified.z << 4 + 8);
|
||||
return new BlockPos((mostRecentlyModified.x << 4) + 8, 0, (mostRecentlyModified.z << 4) + 8);
|
||||
}
|
||||
|
||||
private synchronized List<CachedRegion> allRegions() {
|
||||
|
||||
36
src/main/java/baritone/cache/ChunkPacker.java
vendored
36
src/main/java/baritone/cache/ChunkPacker.java
vendored
@@ -17,12 +17,12 @@
|
||||
|
||||
package baritone.cache;
|
||||
|
||||
import baritone.api.utils.BlockUtils;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.utils.pathing.PathingBlockType;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.chunk.BlockStateContainer;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
@@ -36,8 +36,6 @@ import java.util.*;
|
||||
*/
|
||||
public final class ChunkPacker {
|
||||
|
||||
private static final Map<String, Block> resourceCache = new HashMap<>();
|
||||
|
||||
private ChunkPacker() {}
|
||||
|
||||
public static CachedChunk pack(Chunk chunk) {
|
||||
@@ -75,7 +73,7 @@ public final class ChunkPacker {
|
||||
bitSet.set(index + 1, bits[1]);
|
||||
Block block = state.getBlock();
|
||||
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(block)) {
|
||||
String name = blockToString(block);
|
||||
String name = BlockUtils.blockToString(block);
|
||||
specialBlocks.computeIfAbsent(name, b -> new ArrayList<>()).add(new BlockPos(x, y, z));
|
||||
}
|
||||
}
|
||||
@@ -105,25 +103,6 @@ public final class ChunkPacker {
|
||||
return new CachedChunk(chunk.x, chunk.z, bitSet, blocks, specialBlocks, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public static String blockToString(Block block) {
|
||||
ResourceLocation loc = Block.REGISTRY.getNameForObject(block);
|
||||
String name = loc.getPath(); // normally, only write the part after the minecraft:
|
||||
if (!loc.getNamespace().equals("minecraft")) {
|
||||
// Baritone is running on top of forge with mods installed, perhaps?
|
||||
name = loc.toString(); // include the namespace with the colon
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public static Block stringToBlockRequired(String name) {
|
||||
Block block = stringToBlockNullable(name);
|
||||
Objects.requireNonNull(block);
|
||||
return block;
|
||||
}
|
||||
|
||||
public static Block stringToBlockNullable(String name) {
|
||||
return resourceCache.computeIfAbsent(name, n -> Block.getBlockFromName(n.contains(":") ? n : "minecraft:" + n));
|
||||
}
|
||||
|
||||
private static PathingBlockType getPathingBlockType(IBlockState state, Chunk chunk, int x, int y, int z) {
|
||||
Block block = state.getBlock();
|
||||
@@ -133,15 +112,20 @@ public final class ChunkPacker {
|
||||
if (MovementHelper.possiblyFlowing(state)) {
|
||||
return PathingBlockType.AVOID;
|
||||
}
|
||||
if (
|
||||
(x != 15 && MovementHelper.possiblyFlowing(chunk.getBlockState(x + 1, y, z)))
|
||||
|| (x != 0 && MovementHelper.possiblyFlowing(chunk.getBlockState(x - 1, y, z)))
|
||||
|| (z != 15 && MovementHelper.possiblyFlowing(chunk.getBlockState(x, y, z + 1)))
|
||||
|| (z != 0 && MovementHelper.possiblyFlowing(chunk.getBlockState(x, y, z - 1)))
|
||||
) {
|
||||
return PathingBlockType.AVOID;
|
||||
}
|
||||
if (x == 0 || x == 15 || z == 0 || z == 15) {
|
||||
if (BlockLiquid.getSlopeAngle(chunk.getWorld(), new BlockPos(x + chunk.x << 4, y, z + chunk.z << 4), state.getMaterial(), state) == -1000.0F) {
|
||||
return PathingBlockType.WATER;
|
||||
}
|
||||
return PathingBlockType.AVOID;
|
||||
}
|
||||
if (MovementHelper.possiblyFlowing(chunk.getBlockState(x + 1, y, z)) || MovementHelper.possiblyFlowing(chunk.getBlockState(x - 1, y, z)) || MovementHelper.possiblyFlowing(chunk.getBlockState(x, y, z + 1)) || MovementHelper.possiblyFlowing(chunk.getBlockState(x, y, z - 1))) {
|
||||
return PathingBlockType.AVOID;
|
||||
}
|
||||
return PathingBlockType.WATER;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package baritone.cache;
|
||||
|
||||
import baritone.api.cache.IWaypoint;
|
||||
import baritone.api.cache.IWaypointCollection;
|
||||
import baritone.api.cache.Waypoint;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
@@ -19,7 +19,7 @@ package baritone.cache;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.cache.IWorldProvider;
|
||||
import baritone.utils.Helper;
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.utils.accessor.IAnvilChunkLoader;
|
||||
import baritone.utils.accessor.IChunkProviderServer;
|
||||
import net.minecraft.server.integrated.IntegratedServer;
|
||||
|
||||
38
src/main/java/baritone/cache/WorldScanner.java
vendored
38
src/main/java/baritone/cache/WorldScanner.java
vendored
@@ -28,15 +28,15 @@ import net.minecraft.world.chunk.BlockStateContainer;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public enum WorldScanner implements IWorldScanner {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
private static final int[] DEFAULT_COORDINATE_ITERATION_ORDER = IntStream.range(0, 16).toArray();
|
||||
|
||||
@Override
|
||||
public List<BlockPos> scanChunkRadius(IPlayerContext ctx, List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius) {
|
||||
if (blocks.contains(null)) {
|
||||
@@ -53,6 +53,9 @@ public enum WorldScanner implements IWorldScanner {
|
||||
int playerChunkZ = ctx.playerFeet().getZ() >> 4;
|
||||
int playerY = ctx.playerFeet().getY();
|
||||
|
||||
int playerYBlockStateContainerIndex = playerY >> 4;
|
||||
int[] coordinateIterationOrder = IntStream.range(0, 16).boxed().sorted(Comparator.comparingInt(y -> Math.abs(y - playerYBlockStateContainerIndex))).mapToInt(x -> x).toArray();
|
||||
|
||||
int searchRadiusSq = 0;
|
||||
boolean foundWithinY = false;
|
||||
while (true) {
|
||||
@@ -72,7 +75,9 @@ public enum WorldScanner implements IWorldScanner {
|
||||
continue;
|
||||
}
|
||||
allUnloaded = false;
|
||||
scanChunkInto(chunkX << 4, chunkZ << 4, chunk, blocks, res, max, yLevelThreshold, playerY);
|
||||
if (scanChunkInto(chunkX << 4, chunkZ << 4, chunk, blocks, res, max, yLevelThreshold, playerY, coordinateIterationOrder)) {
|
||||
foundWithinY = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((allUnloaded && foundChunks)
|
||||
@@ -100,13 +105,15 @@ public enum WorldScanner implements IWorldScanner {
|
||||
}
|
||||
|
||||
ArrayList<BlockPos> res = new ArrayList<>();
|
||||
scanChunkInto(pos.x << 4, pos.z << 4, chunk, blocks, res, max, yLevelThreshold, playerY);
|
||||
scanChunkInto(pos.x << 4, pos.z << 4, chunk, blocks, res, max, yLevelThreshold, playerY, DEFAULT_COORDINATE_ITERATION_ORDER);
|
||||
return res;
|
||||
}
|
||||
|
||||
public void scanChunkInto(int chunkX, int chunkZ, Chunk chunk, List<Block> search, Collection<BlockPos> result, int max, int yLevelThreshold, int playerY) {
|
||||
private boolean scanChunkInto(int chunkX, int chunkZ, Chunk chunk, List<Block> search, Collection<BlockPos> result, int max, int yLevelThreshold, int playerY, int[] coordinateIterationOrder) {
|
||||
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
|
||||
for (int y0 = 0; y0 < 16; y0++) {
|
||||
boolean foundWithinY = false;
|
||||
for (int yIndex = 0; yIndex < 16; yIndex++) {
|
||||
int y0 = coordinateIterationOrder[yIndex];
|
||||
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
|
||||
if (extendedblockstorage == null) {
|
||||
continue;
|
||||
@@ -121,14 +128,23 @@ public enum WorldScanner implements IWorldScanner {
|
||||
IBlockState state = bsc.get(x, y, z);
|
||||
if (search.contains(state.getBlock())) {
|
||||
int yy = yReal | y;
|
||||
result.add(new BlockPos(chunkX | x, yy, chunkZ | z));
|
||||
if (result.size() >= max && Math.abs(yy - playerY) < yLevelThreshold) {
|
||||
return;
|
||||
if (result.size() >= max) {
|
||||
if (Math.abs(yy - playerY) < yLevelThreshold) {
|
||||
foundWithinY = true;
|
||||
} else {
|
||||
if (foundWithinY) {
|
||||
// have found within Y in this chunk, so don't need to consider outside Y
|
||||
// TODO continue iteration to one more sorted Y coordinate block
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
result.add(new BlockPos(chunkX | x, yy, chunkZ | z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return foundWithinY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,9 @@ import baritone.api.event.events.*;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import baritone.api.event.listener.IEventBus;
|
||||
import baritone.api.event.listener.IGameEventListener;
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.cache.WorldProvider;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.Helper;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@ import baritone.api.pathing.calc.IPath;
|
||||
import baritone.api.pathing.calc.IPathFinder;
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.api.utils.PathCalculationResult;
|
||||
import baritone.pathing.movement.CalculationContext;
|
||||
import baritone.utils.Helper;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
|
||||
import java.util.Optional;
|
||||
@@ -186,7 +186,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder, Helper {
|
||||
}
|
||||
|
||||
protected Optional<IPath> bestSoFar(boolean logInfo, int numNodes) {
|
||||
if (startNode == null || bestSoFar == null) {
|
||||
if (startNode == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
double bestDist = 0;
|
||||
|
||||
@@ -21,11 +21,11 @@ import baritone.api.pathing.calc.IPath;
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
import baritone.api.pathing.movement.IMovement;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.pathing.movement.CalculationContext;
|
||||
import baritone.pathing.movement.Movement;
|
||||
import baritone.pathing.movement.Moves;
|
||||
import baritone.pathing.path.CutoffPath;
|
||||
import baritone.utils.Helper;
|
||||
import baritone.utils.pathing.PathBase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -60,6 +60,7 @@ public class CalculationContext {
|
||||
public final boolean allowJumpAt256;
|
||||
public final boolean assumeWalkOnWater;
|
||||
public final boolean allowDiagonalDescend;
|
||||
public final boolean allowDownward;
|
||||
public final int maxFallHeightNoWater;
|
||||
public final int maxFallHeightBucket;
|
||||
public final double waterWalkSpeed;
|
||||
@@ -91,6 +92,7 @@ public class CalculationContext {
|
||||
this.allowJumpAt256 = Baritone.settings().allowJumpAt256.value;
|
||||
this.assumeWalkOnWater = Baritone.settings().assumeWalkOnWater.value;
|
||||
this.allowDiagonalDescend = Baritone.settings().allowDiagonalDescend.value;
|
||||
this.allowDownward = Baritone.settings().allowDownward.value;
|
||||
this.maxFallHeightNoWater = Baritone.settings().maxFallHeightNoWater.value;
|
||||
this.maxFallHeightBucket = Baritone.settings().maxFallHeightBucket.value;
|
||||
int depth = EnchantmentHelper.getDepthStriderModifier(player);
|
||||
|
||||
@@ -270,4 +270,8 @@ public abstract class Movement implements IMovement, MovementHelper {
|
||||
}
|
||||
return toWalkIntoCached;
|
||||
}
|
||||
|
||||
public BlockPos[] toBreakAll() {
|
||||
return positionsToBreak;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import baritone.api.utils.*;
|
||||
import baritone.api.utils.input.Input;
|
||||
import baritone.pathing.movement.MovementState.MovementTarget;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.Helper;
|
||||
import baritone.utils.ToolSet;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.properties.PropertyBool;
|
||||
@@ -56,7 +55,8 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
|| bsi.get0(x + 1, y, z).getBlock() instanceof BlockLiquid
|
||||
|| bsi.get0(x - 1, y, z).getBlock() instanceof BlockLiquid
|
||||
|| bsi.get0(x, y, z + 1).getBlock() instanceof BlockLiquid
|
||||
|| bsi.get0(x, y, z - 1).getBlock() instanceof BlockLiquid;
|
||||
|| bsi.get0(x, y, z - 1).getBlock() instanceof BlockLiquid
|
||||
|| Baritone.settings().blocksToAvoidBreaking.value.contains(b);
|
||||
}
|
||||
|
||||
static boolean canWalkThrough(IPlayerContext ctx, BetterBlockPos pos) {
|
||||
@@ -75,6 +75,9 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
if (block == Blocks.FIRE || block == Blocks.TRIPWIRE || block == Blocks.WEB || block == Blocks.END_PORTAL || block == Blocks.COCOA || block instanceof BlockSkull || block instanceof BlockTrapDoor) {
|
||||
return false;
|
||||
}
|
||||
if (Baritone.settings().blocksToAvoid.value.contains(block)) {
|
||||
return false;
|
||||
}
|
||||
if (block instanceof BlockDoor || block instanceof BlockFenceGate) {
|
||||
// Because there's no nice method in vanilla to check if a door is openable or not, we just have to assume
|
||||
// that anything that isn't an iron door isn't openable, ignoring that some doors introduced in mods can't
|
||||
@@ -290,6 +293,9 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
// if assumeWalkOnWater is off, we can only walk on water if there is water above it
|
||||
return isWater(up) ^ Baritone.settings().assumeWalkOnWater.value;
|
||||
}
|
||||
if (Baritone.settings().assumeWalkOnLava.value && isLava(block) && !isFlowing(x, y, z, state, bsi)) {
|
||||
return true;
|
||||
}
|
||||
if (block == Blocks.GLASS || block == Blocks.STAINED_GLASS) {
|
||||
return true;
|
||||
}
|
||||
@@ -309,6 +315,10 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
return canWalkOn(new BlockStateInterface(ctx), pos.x, pos.y, pos.z, state);
|
||||
}
|
||||
|
||||
static boolean canWalkOn(IPlayerContext ctx, BlockPos pos) {
|
||||
return canWalkOn(new BlockStateInterface(ctx), pos.getX(), pos.getY(), pos.getZ());
|
||||
}
|
||||
|
||||
static boolean canWalkOn(IPlayerContext ctx, BetterBlockPos pos) {
|
||||
return canWalkOn(new BlockStateInterface(ctx), pos.x, pos.y, pos.z);
|
||||
}
|
||||
@@ -478,8 +488,8 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
BlockPos against1 = placeAt.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]);
|
||||
if (MovementHelper.canPlaceAgainst(ctx, against1)) {
|
||||
if (!((Baritone) baritone).getInventoryBehavior().selectThrowawayForLocation(placeAt.getX(), placeAt.getY(), placeAt.getZ())) { // get ready to place a throwaway block
|
||||
Helper.HELPER.logDebug("bb pls get me some blocks. dirt or cobble");
|
||||
if (!((Baritone) baritone).getInventoryBehavior().selectThrowawayForLocation(false, placeAt.getX(), placeAt.getY(), placeAt.getZ())) { // get ready to place a throwaway block
|
||||
Helper.HELPER.logDebug("bb pls get me some blocks. dirt, netherrack, cobble");
|
||||
state.setStatus(MovementStatus.UNREACHABLE);
|
||||
return PlaceResult.NO_OPTION;
|
||||
}
|
||||
@@ -505,10 +515,15 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
EnumFacing side = ctx.objectMouseOver().sideHit;
|
||||
// only way for selectedBlock.equals(placeAt) to be true is if it's replacable
|
||||
if (selectedBlock.equals(placeAt) || (MovementHelper.canPlaceAgainst(ctx, selectedBlock) && selectedBlock.offset(side).equals(placeAt))) {
|
||||
((Baritone) baritone).getInventoryBehavior().selectThrowawayForLocation(true, placeAt.getX(), placeAt.getY(), placeAt.getZ());
|
||||
return PlaceResult.READY_TO_PLACE;
|
||||
}
|
||||
}
|
||||
return found ? PlaceResult.ATTEMPTING : PlaceResult.NO_OPTION;
|
||||
if (found) {
|
||||
((Baritone) baritone).getInventoryBehavior().selectThrowawayForLocation(true, placeAt.getX(), placeAt.getY(), placeAt.getZ());
|
||||
return PlaceResult.ATTEMPTING;
|
||||
}
|
||||
return PlaceResult.NO_OPTION;
|
||||
}
|
||||
|
||||
enum PlaceResult {
|
||||
|
||||
@@ -198,8 +198,6 @@ public class MovementAscend extends Movement {
|
||||
return state.setInput(Input.JUMP, true);
|
||||
}
|
||||
|
||||
|
||||
// System.out.println(flatDistToNext + " " + sideDist);
|
||||
if (flatDistToNext > 1.2 || sideDist > 0.2) {
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,9 @@ public class MovementDownward extends Movement {
|
||||
}
|
||||
|
||||
public static double cost(CalculationContext context, int x, int y, int z) {
|
||||
if (!context.allowDownward) {
|
||||
return COST_INF;
|
||||
}
|
||||
if (!MovementHelper.canWalkOn(context.bsi, x, y - 2, z)) {
|
||||
return COST_INF;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ import net.minecraft.init.Items;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
|
||||
@@ -92,8 +91,7 @@ public class MovementFall extends Movement {
|
||||
|
||||
targetRotation = new Rotation(toDest.getYaw(), 90.0F);
|
||||
|
||||
RayTraceResult trace = ctx.objectMouseOver();
|
||||
if (trace != null && trace.typeOfHit == RayTraceResult.Type.BLOCK && (trace.getBlockPos().equals(dest) || trace.getBlockPos().equals(dest.down()))) {
|
||||
if (ctx.isLookingAt(dest) || ctx.isLookingAt(dest.down())) {
|
||||
state.setInput(Input.CLICK_RIGHT, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +106,9 @@ public class MovementParkour extends Movement {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (MovementHelper.canWalkOn(context.bsi, x + xDiff * i, y - 1, z + zDiff * i)) {
|
||||
IBlockState landingOn = context.bsi.get0(x + xDiff * i, y - 1, z + zDiff * i);
|
||||
// farmland needs to be canwalkon otherwise farm can never work at all, but we want to specifically disallow ending a jumy on farmland haha
|
||||
if (landingOn.getBlock() != Blocks.FARMLAND && MovementHelper.canWalkOn(context.bsi, x + xDiff * i, y - 1, z + zDiff * i, landingOn)) {
|
||||
res.x = x + xDiff * i;
|
||||
res.y = y;
|
||||
res.z = z + zDiff * i;
|
||||
|
||||
@@ -208,7 +208,7 @@ public class MovementPillar extends Movement {
|
||||
return state;
|
||||
} else {
|
||||
// Get ready to place a throwaway block
|
||||
if (!((Baritone) baritone).getInventoryBehavior().selectThrowawayForLocation(src.x, src.y, src.z)) {
|
||||
if (!((Baritone) baritone).getInventoryBehavior().selectThrowawayForLocation(true, src.x, src.y, src.z)) {
|
||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,10 +30,7 @@ import baritone.pathing.movement.Movement;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.pathing.movement.MovementState;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockDoor;
|
||||
import net.minecraft.block.BlockFenceGate;
|
||||
import net.minecraft.block.BlockSlab;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@@ -151,6 +148,8 @@ public class MovementTraverse extends Movement {
|
||||
@Override
|
||||
public MovementState updateState(MovementState state) {
|
||||
super.updateState(state);
|
||||
IBlockState pb0 = BlockStateInterface.get(ctx, positionsToBreak[0]);
|
||||
IBlockState pb1 = BlockStateInterface.get(ctx, positionsToBreak[1]);
|
||||
if (state.getStatus() != MovementStatus.RUNNING) {
|
||||
// if the setting is enabled
|
||||
if (!Baritone.settings().walkWhileBreaking.value) {
|
||||
@@ -161,10 +160,10 @@ public class MovementTraverse extends Movement {
|
||||
return state;
|
||||
}
|
||||
// and if it's fine to walk into the blocks in front
|
||||
if (MovementHelper.avoidWalkingInto(BlockStateInterface.get(ctx, positionsToBreak[0]).getBlock())) {
|
||||
if (MovementHelper.avoidWalkingInto(pb0.getBlock())) {
|
||||
return state;
|
||||
}
|
||||
if (MovementHelper.avoidWalkingInto(BlockStateInterface.get(ctx, positionsToBreak[1]).getBlock())) {
|
||||
if (MovementHelper.avoidWalkingInto(pb1.getBlock())) {
|
||||
return state;
|
||||
}
|
||||
// and we aren't already pressed up against the block
|
||||
@@ -177,6 +176,10 @@ public class MovementTraverse extends Movement {
|
||||
// it's safe to do this since the two blocks we break (in a traverse) are right on top of each other and so will have the same yaw
|
||||
float yawToDest = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), dest), ctx.playerRotations()).getYaw();
|
||||
float pitchToBreak = state.getTarget().getRotation().get().getPitch();
|
||||
if ((pb0.isFullCube() || pb0.getBlock() instanceof BlockAir && (pb1.isFullCube() || pb1.getBlock() instanceof BlockAir))) {
|
||||
// in the meantime, before we're right up against the block, we can break efficiently at this angle
|
||||
pitchToBreak = 26;
|
||||
}
|
||||
|
||||
state.setTarget(new MovementState.MovementTarget(new Rotation(yawToDest, pitchToBreak), true));
|
||||
return state.setInput(Input.MOVE_FORWARD, true).setInput(Input.SPRINT, true);
|
||||
@@ -187,8 +190,6 @@ public class MovementTraverse extends Movement {
|
||||
|
||||
Block fd = BlockStateInterface.get(ctx, src.down()).getBlock();
|
||||
boolean ladder = fd == Blocks.LADDER || fd == Blocks.VINE;
|
||||
IBlockState pb0 = BlockStateInterface.get(ctx, positionsToBreak[0]);
|
||||
IBlockState pb1 = BlockStateInterface.get(ctx, positionsToBreak[1]);
|
||||
|
||||
boolean door = pb0.getBlock() instanceof BlockDoor || pb1.getBlock() instanceof BlockDoor;
|
||||
if (door) {
|
||||
@@ -245,12 +246,13 @@ public class MovementTraverse extends Movement {
|
||||
if (wasTheBridgeBlockAlwaysThere && (!MovementHelper.isLiquid(ctx, ctx.playerFeet()) || Baritone.settings().sprintInWater.value) && (!MovementHelper.avoidWalkingInto(intoBelow) || MovementHelper.isWater(intoBelow)) && !MovementHelper.avoidWalkingInto(intoAbove)) {
|
||||
state.setInput(Input.SPRINT, true);
|
||||
}
|
||||
Block destDown = BlockStateInterface.get(ctx, dest.down()).getBlock();
|
||||
if (whereAmI.getY() != dest.getY() && ladder && (destDown == Blocks.VINE || destDown == Blocks.LADDER)) {
|
||||
new MovementPillar(baritone, dest.down(), dest).updateState(state); // i'm sorry
|
||||
return state;
|
||||
|
||||
IBlockState destDown = BlockStateInterface.get(ctx, dest.down());
|
||||
BlockPos against = positionsToBreak[0];
|
||||
if (whereAmI.getY() != dest.getY() && ladder && (destDown.getBlock() == Blocks.VINE || destDown.getBlock() == Blocks.LADDER)) {
|
||||
against = destDown.getBlock() == Blocks.VINE ? MovementPillar.getAgainst(new CalculationContext(baritone), dest.down()) : dest.offset(destDown.getValue(BlockLadder.FACING).getOpposite());
|
||||
}
|
||||
MovementHelper.moveTowards(ctx, state, positionsToBreak[0]);
|
||||
MovementHelper.moveTowards(ctx, state, against);
|
||||
return state;
|
||||
} else {
|
||||
wasTheBridgeBlockAlwaysThere = false;
|
||||
|
||||
@@ -23,10 +23,7 @@ import baritone.api.pathing.movement.ActionCosts;
|
||||
import baritone.api.pathing.movement.IMovement;
|
||||
import baritone.api.pathing.movement.MovementStatus;
|
||||
import baritone.api.pathing.path.IPathExecutor;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
import baritone.api.utils.RotationUtils;
|
||||
import baritone.api.utils.VecUtils;
|
||||
import baritone.api.utils.*;
|
||||
import baritone.api.utils.input.Input;
|
||||
import baritone.behavior.PathingBehavior;
|
||||
import baritone.pathing.calc.AbstractNodeCostSearch;
|
||||
@@ -35,7 +32,6 @@ import baritone.pathing.movement.Movement;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.pathing.movement.movements.*;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.Helper;
|
||||
import net.minecraft.block.BlockLiquid;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.Tuple;
|
||||
@@ -441,7 +437,10 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
IMovement prev = path.movements().get(pathPosition - 1);
|
||||
if (prev instanceof MovementDescend && prev.getDirection().up().equals(current.getDirection().down())) {
|
||||
BlockPos center = current.getSrc().up();
|
||||
if (ctx.player().posY >= center.getY()) { // playerFeet adds 0.1251 to account for soul sand
|
||||
// playerFeet adds 0.1251 to account for soul sand
|
||||
// farmland is 0.9375
|
||||
// 0.07 is to account for farmland
|
||||
if (ctx.player().posY >= center.getY() - 0.07) {
|
||||
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.JUMP, false);
|
||||
return true;
|
||||
}
|
||||
@@ -566,7 +565,10 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
if (next instanceof MovementDescend && next.getDirection().equals(current.getDirection())) {
|
||||
return true;
|
||||
}
|
||||
if (next instanceof MovementTraverse && next.getDirection().down().equals(current.getDirection()) && MovementHelper.canWalkOn(ctx, next.getDest().down())) {
|
||||
if (!MovementHelper.canWalkOn(ctx, current.getDest().add(current.getDirection()))) {
|
||||
return false;
|
||||
}
|
||||
if (next instanceof MovementTraverse && next.getDirection().down().equals(current.getDirection())) {
|
||||
return true;
|
||||
}
|
||||
return next instanceof MovementDiagonal && Baritone.settings().allowOvershootDiagonalDescend.value;
|
||||
|
||||
141
src/main/java/baritone/process/BackfillProcess.java
Normal file
141
src/main/java/baritone/process/BackfillProcess.java
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.process;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.process.PathingCommand;
|
||||
import baritone.api.process.PathingCommandType;
|
||||
import baritone.api.utils.input.Input;
|
||||
import baritone.pathing.movement.Movement;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.pathing.movement.MovementState;
|
||||
import baritone.pathing.path.PathExecutor;
|
||||
import baritone.utils.BaritoneProcessHelper;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.chunk.EmptyChunk;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class BackfillProcess extends BaritoneProcessHelper {
|
||||
|
||||
public HashMap<BlockPos, IBlockState> blocksToReplace = new HashMap<>();
|
||||
|
||||
public BackfillProcess(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
if (ctx.player() == null || ctx.world() == null) {
|
||||
return false;
|
||||
}
|
||||
if (!Baritone.settings().backfill.value) {
|
||||
return false;
|
||||
}
|
||||
if (Baritone.settings().allowParkour.value) {
|
||||
logDirect("Backfill cannot be used with allowParkour true");
|
||||
Baritone.settings().backfill.value = false;
|
||||
return false;
|
||||
}
|
||||
amIBreakingABlockHMMMMMMM();
|
||||
for (BlockPos pos : new ArrayList<>(blocksToReplace.keySet())) {
|
||||
if (ctx.world().getChunk(pos) instanceof EmptyChunk) {
|
||||
blocksToReplace.remove(pos);
|
||||
}
|
||||
}
|
||||
baritone.getInputOverrideHandler().clearAllKeys();
|
||||
|
||||
return !toFillIn().isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
||||
if (!isSafeToCancel) {
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
}
|
||||
baritone.getInputOverrideHandler().clearAllKeys();
|
||||
for (BlockPos toPlace : toFillIn()) {
|
||||
MovementState fake = new MovementState();
|
||||
switch (MovementHelper.attemptToPlaceABlock(fake, baritone, toPlace, false)) {
|
||||
case NO_OPTION:
|
||||
continue;
|
||||
case READY_TO_PLACE:
|
||||
baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true);
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
case ATTEMPTING:
|
||||
// patience
|
||||
baritone.getLookBehavior().updateTarget(fake.getTarget().getRotation().get(), true);
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
}
|
||||
}
|
||||
return new PathingCommand(null, PathingCommandType.DEFER); // cede to other process
|
||||
}
|
||||
|
||||
public void amIBreakingABlockHMMMMMMM() {
|
||||
if (!ctx.getSelectedBlock().isPresent()) {
|
||||
return;
|
||||
}
|
||||
blocksToReplace.put(ctx.getSelectedBlock().get(), ctx.world().getBlockState(ctx.getSelectedBlock().get()));
|
||||
}
|
||||
|
||||
public List<BlockPos> toFillIn() {
|
||||
return blocksToReplace
|
||||
.keySet()
|
||||
.stream()
|
||||
.filter(pos -> ctx.world().getBlockState(pos).getBlock() == Blocks.AIR)
|
||||
.filter(pos -> ctx.world().mayPlace(Blocks.DIRT, pos, false, EnumFacing.UP, null))
|
||||
.filter(pos -> !partOfCurrentMovement(pos))
|
||||
.sorted(Comparator.<BlockPos>comparingDouble(ctx.player()::getDistanceSq).reversed())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private boolean partOfCurrentMovement(BlockPos pos) {
|
||||
PathExecutor exec = baritone.getPathingBehavior().getCurrent();
|
||||
if (exec == null || exec.finished() || exec.failed()) {
|
||||
return false;
|
||||
}
|
||||
Movement movement = (Movement) exec.getPath().movements().get(exec.getPosition());
|
||||
return Arrays.asList(movement.toBreakAll()).contains(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLostControl() {
|
||||
if (blocksToReplace != null && !blocksToReplace.isEmpty()) {
|
||||
blocksToReplace.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayName0() {
|
||||
return "Backfill";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTemporary() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double priority() {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,6 @@ import baritone.utils.PathingCommandContext;
|
||||
import baritone.utils.schematic.AirSchematic;
|
||||
import baritone.utils.schematic.Schematic;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -56,27 +55,35 @@ import static baritone.api.pathing.movement.ActionCosts.COST_INF;
|
||||
|
||||
public class BuilderProcess extends BaritoneProcessHelper implements IBuilderProcess {
|
||||
|
||||
public BuilderProcess(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
|
||||
private HashSet<BetterBlockPos> incorrectPositions;
|
||||
private String name;
|
||||
private ISchematic realSchematic;
|
||||
private ISchematic schematic;
|
||||
private Vec3i origin;
|
||||
private int ticks;
|
||||
private boolean paused;
|
||||
private int layer;
|
||||
|
||||
public boolean build(String schematicFile, BlockPos origin) {
|
||||
File file = new File(new File(Minecraft.getMinecraft().gameDir, "schematics"), schematicFile);
|
||||
System.out.println(file + " " + file.exists());
|
||||
return build(schematicFile, file, origin);
|
||||
public BuilderProcess(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(String name, ISchematic schematic, Vec3i origin) {
|
||||
this.name = name;
|
||||
this.schematic = schematic;
|
||||
this.realSchematic = null;
|
||||
this.origin = origin;
|
||||
this.paused = false;
|
||||
this.layer = 0;
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
paused = false;
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
paused = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -154,10 +161,10 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
}
|
||||
|
||||
public class Placement {
|
||||
final int hotbarSelection;
|
||||
final BlockPos placeAgainst;
|
||||
final EnumFacing side;
|
||||
final Rotation rot;
|
||||
private final int hotbarSelection;
|
||||
private final BlockPos placeAgainst;
|
||||
private final EnumFacing side;
|
||||
private final Rotation rot;
|
||||
|
||||
public Placement(int hotbarSelection, BlockPos placeAgainst, EnumFacing side, Rotation rot) {
|
||||
this.hotbarSelection = hotbarSelection;
|
||||
@@ -269,34 +276,72 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
double z = side.getZOffset() == 0 ? 0.5 : (1 + side.getZOffset()) / 2D;
|
||||
return new Vec3d[]{new Vec3d(x, 0.25, z), new Vec3d(x, 0.75, z)};
|
||||
default: // null
|
||||
throw new NullPointerException();
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
||||
// TODO somehow tell inventorybehavior what we'd like to have on the hotbar
|
||||
// perhaps take the 16 closest positions in incorrectPositions to ctx.playerFeet that aren't desired to be air, and then snag the top 4 most common block states, then request those on the hotbar
|
||||
|
||||
|
||||
// this will work as is, but it'll be trashy
|
||||
// need to iterate over incorrectPositions and see which ones we can "correct" from our current standing position
|
||||
|
||||
baritone.getInputOverrideHandler().clearAllKeys();
|
||||
BuilderCalculationContext bcc = new BuilderCalculationContext();
|
||||
if (!recalc(bcc)) {
|
||||
logDirect("Done building");
|
||||
onLostControl();
|
||||
return null;
|
||||
}
|
||||
trim(bcc);
|
||||
if (baritone.getInputOverrideHandler().isInputForcedDown(Input.CLICK_LEFT)) {
|
||||
ticks = 5;
|
||||
} else {
|
||||
ticks--;
|
||||
}
|
||||
Optional<Tuple<BetterBlockPos, Rotation>> toBreak = toBreakNearPlayer(bcc);
|
||||
baritone.getInputOverrideHandler().clearAllKeys();
|
||||
if (paused) {
|
||||
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||
}
|
||||
if (Baritone.settings().buildInLayers.value) {
|
||||
if (realSchematic == null) {
|
||||
realSchematic = schematic;
|
||||
}
|
||||
schematic = new ISchematic() {
|
||||
@Override
|
||||
public IBlockState desiredState(int x, int y, int z) {
|
||||
return realSchematic.desiredState(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int widthX() {
|
||||
return realSchematic.widthX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int heightY() {
|
||||
return layer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lengthZ() {
|
||||
return realSchematic.lengthZ();
|
||||
}
|
||||
};
|
||||
}
|
||||
BuilderCalculationContext bcc = new BuilderCalculationContext();
|
||||
if (!recalc(bcc)) {
|
||||
if (Baritone.settings().buildInLayers.value && layer < realSchematic.heightY()) {
|
||||
logDirect("Starting layer " + layer);
|
||||
layer++;
|
||||
return onTick(calcFailed, isSafeToCancel);
|
||||
}
|
||||
int distance = Baritone.settings().buildRepeatDistance.value;
|
||||
EnumFacing direction = Baritone.settings().buildRepeatDirection.value;
|
||||
if (distance == 0) {
|
||||
logDirect("Done building");
|
||||
onLostControl();
|
||||
return null;
|
||||
}
|
||||
// build repeat time
|
||||
if (distance == -1) {
|
||||
distance = schematic.size(direction.getAxis());
|
||||
}
|
||||
layer = 0;
|
||||
origin = new BlockPos(origin).offset(direction, distance);
|
||||
logDirect("Repeating build " + distance + " blocks to the " + direction + ", new origin is " + origin);
|
||||
}
|
||||
trim(bcc);
|
||||
|
||||
Optional<Tuple<BetterBlockPos, Rotation>> toBreak = toBreakNearPlayer(bcc);
|
||||
if (toBreak.isPresent() && isSafeToCancel && ctx.player().onGround) {
|
||||
// we'd like to pause to break this block
|
||||
// only change look direction if it's safe (don't want to fuck up an in progress parkour for example
|
||||
@@ -310,10 +355,10 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
// and is unable since it's unsneaked in the intermediary tick
|
||||
baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, true);
|
||||
}
|
||||
if (Objects.equals(ctx.objectMouseOver().getBlockPos(), pos) || ctx.playerRotations().isReallyCloseTo(rot)) {
|
||||
if (ctx.isLookingAt(pos) || ctx.playerRotations().isReallyCloseTo(rot)) {
|
||||
baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_LEFT, true);
|
||||
}
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||
}
|
||||
List<IBlockState> desirableOnHotbar = new ArrayList<>();
|
||||
Optional<Placement> toPlace = searchForPlacables(bcc, desirableOnHotbar);
|
||||
@@ -322,10 +367,10 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
baritone.getLookBehavior().updateTarget(rot, true);
|
||||
ctx.player().inventory.currentItem = toPlace.get().hotbarSelection;
|
||||
baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, true);
|
||||
if ((Objects.equals(ctx.objectMouseOver().getBlockPos(), toPlace.get().placeAgainst) && ctx.objectMouseOver().sideHit.equals(toPlace.get().side)) || ctx.playerRotations().isReallyCloseTo(rot)) {
|
||||
if ((ctx.isLookingAt(toPlace.get().placeAgainst) && ctx.objectMouseOver().sideHit.equals(toPlace.get().side)) || ctx.playerRotations().isReallyCloseTo(rot)) {
|
||||
baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true);
|
||||
}
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||
}
|
||||
|
||||
List<IBlockState> approxPlacable = placable(36);
|
||||
@@ -359,9 +404,9 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
if (goal == null) {
|
||||
goal = assemble(bcc, approxPlacable); // we're far away, so assume that we have our whole inventory to recalculate placable properly
|
||||
if (goal == null) {
|
||||
logDirect("Unable to do it =(");
|
||||
onLostControl();
|
||||
return null;
|
||||
logDirect("Unable to do it. Pausing. resume to resume, cancel to cancel");
|
||||
paused = true;
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
}
|
||||
}
|
||||
return new PathingCommandContext(goal, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH, bcc);
|
||||
@@ -417,10 +462,8 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
for (int y = 0; y < schematic.heightY(); y++) {
|
||||
for (int z = 0; z < schematic.lengthZ(); z++) {
|
||||
for (int x = 0; x < schematic.widthX(); x++) {
|
||||
if (schematic.inSchematic(x, y, z)) {
|
||||
if (!valid(bcc.bsi.get0(x + origin.getX(), y + origin.getY(), z + origin.getZ()), schematic.desiredState(x, y, z))) {
|
||||
incorrectPositions.add(new BetterBlockPos(x + origin.getX(), y + origin.getY(), z + origin.getZ()));
|
||||
}
|
||||
if (schematic.inSchematic(x, y, z) && !valid(bcc.bsi.get0(x + origin.getX(), y + origin.getY(), z + origin.getZ()), schematic.desiredState(x, y, z))) {
|
||||
incorrectPositions.add(new BetterBlockPos(x + origin.getX(), y + origin.getY(), z + origin.getZ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -498,7 +541,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
}
|
||||
|
||||
public static class GoalAdjacent extends GoalGetToBlock {
|
||||
boolean allowSameLevel;
|
||||
private boolean allowSameLevel;
|
||||
|
||||
public GoalAdjacent(BlockPos pos, boolean allowSameLevel) {
|
||||
super(pos);
|
||||
@@ -540,11 +583,14 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
incorrectPositions = null;
|
||||
name = null;
|
||||
schematic = null;
|
||||
realSchematic = null;
|
||||
layer = 0;
|
||||
paused = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayName0() {
|
||||
return "Building " + name;
|
||||
return paused ? "Builder Paused" : "Building " + name;
|
||||
}
|
||||
|
||||
public List<IBlockState> placable(int size) {
|
||||
|
||||
@@ -90,6 +90,9 @@ public class CustomGoalProcess extends BaritoneProcessHelper implements ICustomG
|
||||
}
|
||||
if (this.goal == null || (this.goal.isInGoal(ctx.playerFeet()) && this.goal.isInGoal(baritone.getPathingBehavior().pathStart()))) {
|
||||
onLostControl(); // we're there xd
|
||||
if (Baritone.settings().disconnectOnArrival.value) {
|
||||
ctx.world().sendQuittingDisconnectingPacket();
|
||||
}
|
||||
return new PathingCommand(this.goal, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||
}
|
||||
return new PathingCommand(this.goal, PathingCommandType.SET_GOAL_AND_PATH);
|
||||
|
||||
@@ -22,19 +22,30 @@ import baritone.api.cache.ICachedWorld;
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
import baritone.api.pathing.goals.GoalComposite;
|
||||
import baritone.api.pathing.goals.GoalXZ;
|
||||
import baritone.api.process.IExploreProcess;
|
||||
import baritone.api.process.PathingCommand;
|
||||
import baritone.api.process.PathingCommandType;
|
||||
import baritone.api.utils.MyChunkPos;
|
||||
import baritone.cache.CachedWorld;
|
||||
import baritone.utils.BaritoneProcessHelper;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ExploreProcess extends BaritoneProcessHelper {
|
||||
public class ExploreProcess extends BaritoneProcessHelper implements IExploreProcess {
|
||||
|
||||
private BlockPos explorationOrigin;
|
||||
|
||||
private IChunkFilter filter;
|
||||
|
||||
public ExploreProcess(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
@@ -44,10 +55,26 @@ public class ExploreProcess extends BaritoneProcessHelper {
|
||||
return explorationOrigin != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void explore(int centerX, int centerZ) {
|
||||
explorationOrigin = new BlockPos(centerX, 0, centerZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyJsonFilter(Path path, boolean invert) throws Exception {
|
||||
filter = new JsonChunkFilter(path, invert);
|
||||
}
|
||||
|
||||
public IChunkFilter calcFilter() {
|
||||
IChunkFilter filter;
|
||||
if (this.filter != null) {
|
||||
filter = new EitherChunk(this.filter, new BaritoneChunkCache());
|
||||
} else {
|
||||
filter = new BaritoneChunkCache();
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
||||
if (calcFailed) {
|
||||
@@ -55,19 +82,23 @@ public class ExploreProcess extends BaritoneProcessHelper {
|
||||
onLostControl();
|
||||
return null;
|
||||
}
|
||||
Goal[] closestUncached = closestUncachedChunks(explorationOrigin);
|
||||
IChunkFilter filter = calcFilter();
|
||||
if (!Baritone.settings().disableCompletionCheck.value && filter.finished()) {
|
||||
logDirect("Explored all chunks");
|
||||
onLostControl();
|
||||
return null;
|
||||
}
|
||||
Goal[] closestUncached = closestUncachedChunks(explorationOrigin, filter);
|
||||
if (closestUncached == null) {
|
||||
logDebug("awaiting region load from disk");
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
}
|
||||
System.out.println("Closest uncached: " + closestUncached);
|
||||
return new PathingCommand(new GoalComposite(closestUncached), PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH);
|
||||
}
|
||||
|
||||
private Goal[] closestUncachedChunks(BlockPos center) {
|
||||
private Goal[] closestUncachedChunks(BlockPos center, IChunkFilter filter) {
|
||||
int chunkX = center.getX() >> 4;
|
||||
int chunkZ = center.getZ() >> 4;
|
||||
ICachedWorld cache = baritone.getWorldProvider().getCurrentWorld().getCachedWorld();
|
||||
for (int dist = 0; ; dist++) {
|
||||
List<BlockPos> centers = new ArrayList<>();
|
||||
for (int dx = -dist; dx <= dist; dx++) {
|
||||
@@ -76,27 +107,143 @@ public class ExploreProcess extends BaritoneProcessHelper {
|
||||
if (trueDist != dist) {
|
||||
continue; // not considering this one just yet in our expanding search
|
||||
}
|
||||
switch (filter.isAlreadyExplored(chunkX + dx, chunkZ + dz)) {
|
||||
case UNKNOWN:
|
||||
return null; // awaiting load
|
||||
case NOT_EXPLORED:
|
||||
break; // note: this breaks the switch not the for
|
||||
case EXPLORED:
|
||||
continue; // note: this continues the for
|
||||
}
|
||||
int centerX = (chunkX + dx) * 16 + 8;
|
||||
int centerZ = (chunkZ + dz) * 18 + 8;
|
||||
|
||||
if (cache.isCached(centerX, centerZ)) {
|
||||
continue;
|
||||
int offset = 16 * Baritone.settings().worldExploringChunkOffset.value;
|
||||
if (dx < 0) {
|
||||
centerX -= offset;
|
||||
} else {
|
||||
centerX += offset;
|
||||
}
|
||||
if (!((CachedWorld) cache).regionLoaded(centerX, centerZ)) {
|
||||
Baritone.getExecutor().execute(() -> {
|
||||
((CachedWorld) cache).tryLoadFromDisk(centerX >> 9, centerZ >> 9);
|
||||
});
|
||||
return null; // we still need to load regions from disk in order to decide properly
|
||||
if (dz < 0) {
|
||||
centerZ -= offset;
|
||||
} else {
|
||||
centerZ += offset;
|
||||
}
|
||||
centers.add(new BlockPos(centerX, 0, centerZ));
|
||||
}
|
||||
}
|
||||
if (!centers.isEmpty()) {
|
||||
if (centers.size() > Baritone.settings().exploreChunkSetMinimumSize.value) {
|
||||
return centers.stream().map(pos -> new GoalXZ(pos.getX(), pos.getZ())).toArray(Goal[]::new);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum Status {
|
||||
EXPLORED, NOT_EXPLORED, UNKNOWN;
|
||||
}
|
||||
|
||||
private interface IChunkFilter {
|
||||
Status isAlreadyExplored(int chunkX, int chunkZ);
|
||||
|
||||
boolean finished();
|
||||
}
|
||||
|
||||
private class BaritoneChunkCache implements IChunkFilter {
|
||||
|
||||
private final ICachedWorld cache = baritone.getWorldProvider().getCurrentWorld().getCachedWorld();
|
||||
|
||||
@Override
|
||||
public Status isAlreadyExplored(int chunkX, int chunkZ) {
|
||||
int centerX = chunkX << 4;
|
||||
int centerZ = chunkZ << 4;
|
||||
if (cache.isCached(centerX, centerZ)) {
|
||||
return Status.EXPLORED;
|
||||
}
|
||||
if (!((CachedWorld) cache).regionLoaded(centerX, centerZ)) {
|
||||
Baritone.getExecutor().execute(() -> {
|
||||
((CachedWorld) cache).tryLoadFromDisk(centerX >> 9, centerZ >> 9);
|
||||
});
|
||||
return Status.UNKNOWN; // we still need to load regions from disk in order to decide properly
|
||||
}
|
||||
return Status.NOT_EXPLORED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean finished() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private class JsonChunkFilter implements IChunkFilter {
|
||||
private final boolean invert; // if true, the list is interpreted as a list of chunks that are NOT explored, if false, the list is interpreted as a list of chunks that ARE explored
|
||||
private final LongOpenHashSet inFilter;
|
||||
private final MyChunkPos[] positions;
|
||||
|
||||
private JsonChunkFilter(Path path, boolean invert) throws Exception { // ioexception, json exception, etc
|
||||
this.invert = invert;
|
||||
Gson gson = new GsonBuilder().create();
|
||||
positions = gson.fromJson(new InputStreamReader(Files.newInputStream(path)), MyChunkPos[].class);
|
||||
logDirect("Loaded " + positions.length + " positions");
|
||||
inFilter = new LongOpenHashSet();
|
||||
for (MyChunkPos mcp : positions) {
|
||||
inFilter.add(ChunkPos.asLong(mcp.x, mcp.z));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Status isAlreadyExplored(int chunkX, int chunkZ) {
|
||||
if (inFilter.contains(ChunkPos.asLong(chunkX, chunkZ)) ^ invert) {
|
||||
// either it's on the list of explored chunks, or it's not on the list of unexplored chunks
|
||||
// either way, we have it
|
||||
return Status.EXPLORED;
|
||||
} else {
|
||||
// either it's not on the list of explored chunks, or it's on the list of unexplored chunks
|
||||
// either way, it depends on if baritone has cached it so defer to that
|
||||
return Status.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean finished() {
|
||||
if (!invert) {
|
||||
// if invert is false, anything not on the list is uncached
|
||||
return false;
|
||||
}
|
||||
// but if invert is true, anything not on the list IS assumed cached
|
||||
// so we are done if everything on our list is cached!
|
||||
BaritoneChunkCache bcc = new BaritoneChunkCache();
|
||||
for (MyChunkPos pos : positions) {
|
||||
if (bcc.isAlreadyExplored(pos.x, pos.z) != Status.EXPLORED) {
|
||||
// either waiting for it or dont have it at all
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true; // we have everything cached
|
||||
}
|
||||
}
|
||||
|
||||
private class EitherChunk implements IChunkFilter {
|
||||
private final IChunkFilter a;
|
||||
private final IChunkFilter b;
|
||||
|
||||
private EitherChunk(IChunkFilter a, IChunkFilter b) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Status isAlreadyExplored(int chunkX, int chunkZ) {
|
||||
if (a.isAlreadyExplored(chunkX, chunkZ) == Status.EXPLORED) {
|
||||
return Status.EXPLORED;
|
||||
}
|
||||
return b.isAlreadyExplored(chunkX, chunkZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean finished() {
|
||||
return a.finished() || b.finished();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLostControl() {
|
||||
explorationOrigin = null;
|
||||
@@ -104,6 +251,6 @@ public class ExploreProcess extends BaritoneProcessHelper {
|
||||
|
||||
@Override
|
||||
public String displayName0() {
|
||||
return "Exploring around " + explorationOrigin + ", currently going to " + new GoalComposite(closestUncachedChunks(explorationOrigin));
|
||||
return "Exploring around " + explorationOrigin + ", currently going to " + new GoalComposite(closestUncachedChunks(explorationOrigin, calcFilter()));
|
||||
}
|
||||
}
|
||||
|
||||
283
src/main/java/baritone/process/FarmProcess.java
Normal file
283
src/main/java/baritone/process/FarmProcess.java
Normal file
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.process;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
import baritone.api.pathing.goals.GoalBlock;
|
||||
import baritone.api.pathing.goals.GoalComposite;
|
||||
import baritone.api.process.IFarmProcess;
|
||||
import baritone.api.process.PathingCommand;
|
||||
import baritone.api.process.PathingCommandType;
|
||||
import baritone.api.utils.Rotation;
|
||||
import baritone.api.utils.RotationUtils;
|
||||
import baritone.api.utils.input.Input;
|
||||
import baritone.cache.WorldScanner;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.utils.BaritoneProcessHelper;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.EnumDyeColor;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemDye;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class FarmProcess extends BaritoneProcessHelper implements IFarmProcess {
|
||||
|
||||
private boolean active;
|
||||
|
||||
private static final List<Item> FARMLAND_PLANTABLE = Arrays.asList(
|
||||
Items.BEETROOT_SEEDS,
|
||||
Items.MELON_SEEDS,
|
||||
Items.WHEAT_SEEDS,
|
||||
Items.PUMPKIN_SEEDS,
|
||||
Items.POTATO,
|
||||
Items.CARROT
|
||||
);
|
||||
|
||||
private static final List<Item> PICKUP_DROPPED = Arrays.asList(
|
||||
Items.BEETROOT_SEEDS,
|
||||
Items.WHEAT,
|
||||
Items.MELON_SEEDS,
|
||||
Items.MELON,
|
||||
Items.WHEAT_SEEDS,
|
||||
Items.WHEAT,
|
||||
Items.PUMPKIN_SEEDS,
|
||||
Items.POTATO,
|
||||
Items.CARROT,
|
||||
Items.BEETROOT,
|
||||
Item.getItemFromBlock(Blocks.PUMPKIN),
|
||||
Item.getItemFromBlock(Blocks.MELON_BLOCK),
|
||||
Items.NETHER_WART,
|
||||
Items.REEDS,
|
||||
Item.getItemFromBlock(Blocks.CACTUS)
|
||||
);
|
||||
|
||||
public FarmProcess(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void farm() {
|
||||
active = true;
|
||||
}
|
||||
|
||||
private enum Harvest {
|
||||
WHEAT((BlockCrops) Blocks.WHEAT),
|
||||
CARROTS((BlockCrops) Blocks.CARROTS),
|
||||
POTATOES((BlockCrops) Blocks.POTATOES),
|
||||
BEETROOT((BlockCrops) Blocks.BEETROOTS),
|
||||
PUMPKIN(Blocks.PUMPKIN, state -> true),
|
||||
MELON(Blocks.MELON_BLOCK, state -> true),
|
||||
NETHERWART(Blocks.NETHER_WART, state -> state.getValue(BlockNetherWart.AGE) >= 3),
|
||||
SUGARCANE(Blocks.REEDS, null) {
|
||||
@Override
|
||||
public boolean readyToHarvest(World world, BlockPos pos, IBlockState state) {
|
||||
return world.getBlockState(pos.down()).getBlock() instanceof BlockReed;
|
||||
}
|
||||
},
|
||||
CACTUS(Blocks.CACTUS, null) {
|
||||
@Override
|
||||
public boolean readyToHarvest(World world, BlockPos pos, IBlockState state) {
|
||||
return world.getBlockState(pos.down()).getBlock() instanceof BlockCactus;
|
||||
}
|
||||
};
|
||||
public final Block block;
|
||||
public final Predicate<IBlockState> readyToHarvest;
|
||||
|
||||
Harvest(BlockCrops blockCrops) {
|
||||
this(blockCrops, blockCrops::isMaxAge);
|
||||
// max age is 7 for wheat, carrots, and potatoes, but 3 for beetroot
|
||||
}
|
||||
|
||||
Harvest(Block block, Predicate<IBlockState> readyToHarvest) {
|
||||
this.block = block;
|
||||
this.readyToHarvest = readyToHarvest;
|
||||
}
|
||||
|
||||
public boolean readyToHarvest(World world, BlockPos pos, IBlockState state) {
|
||||
return readyToHarvest.test(state);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean readyForHarvest(World world, BlockPos pos, IBlockState state) {
|
||||
for (Harvest harvest : Harvest.values()) {
|
||||
if (harvest.block == state.getBlock()) {
|
||||
return harvest.readyToHarvest(world, pos, state);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isPlantable(ItemStack stack) {
|
||||
return FARMLAND_PLANTABLE.contains(stack.getItem());
|
||||
}
|
||||
|
||||
private boolean isBoneMeal(ItemStack stack) {
|
||||
return !stack.isEmpty() && stack.getItem() instanceof ItemDye && EnumDyeColor.byDyeDamage(stack.getMetadata()) == EnumDyeColor.WHITE;
|
||||
}
|
||||
|
||||
private boolean isNetherWart(ItemStack stack) {
|
||||
return !stack.isEmpty() && stack.getItem().equals(Items.NETHER_WART);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
||||
ArrayList<Block> scan = new ArrayList<>();
|
||||
for (Harvest harvest : Harvest.values()) {
|
||||
scan.add(harvest.block);
|
||||
}
|
||||
scan.add(Blocks.FARMLAND);
|
||||
if (Baritone.settings().replantNetherWart.value) {
|
||||
scan.add(Blocks.SOUL_SAND);
|
||||
}
|
||||
|
||||
List<BlockPos> locations = WorldScanner.INSTANCE.scanChunkRadius(ctx, scan, 256, 10, 4);
|
||||
|
||||
List<BlockPos> toBreak = new ArrayList<>();
|
||||
List<BlockPos> openFarmland = new ArrayList<>();
|
||||
List<BlockPos> bonemealable = new ArrayList<>();
|
||||
List<BlockPos> openSoulsand = new ArrayList<>();
|
||||
for (BlockPos pos : locations) {
|
||||
IBlockState state = ctx.world().getBlockState(pos);
|
||||
boolean airAbove = ctx.world().getBlockState(pos.up()).getBlock() instanceof BlockAir;
|
||||
if (state.getBlock() == Blocks.FARMLAND) {
|
||||
if (airAbove) {
|
||||
openFarmland.add(pos);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (state.getBlock() == Blocks.SOUL_SAND) {
|
||||
if (airAbove) {
|
||||
openSoulsand.add(pos);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (readyForHarvest(ctx.world(), pos, state)) {
|
||||
toBreak.add(pos);
|
||||
continue;
|
||||
}
|
||||
if (state.getBlock() instanceof IGrowable) {
|
||||
IGrowable ig = (IGrowable) state.getBlock();
|
||||
if (ig.canGrow(ctx.world(), pos, state, true) && ig.canUseBonemeal(ctx.world(), ctx.world().rand, pos, state)) {
|
||||
bonemealable.add(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
baritone.getInputOverrideHandler().clearAllKeys();
|
||||
for (BlockPos pos : toBreak) {
|
||||
Optional<Rotation> rot = RotationUtils.reachable(ctx, pos);
|
||||
if (rot.isPresent() && isSafeToCancel) {
|
||||
baritone.getLookBehavior().updateTarget(rot.get(), true);
|
||||
MovementHelper.switchToBestToolFor(ctx, ctx.world().getBlockState(pos));
|
||||
if (ctx.isLookingAt(pos)) {
|
||||
baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_LEFT, true);
|
||||
}
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
}
|
||||
}
|
||||
ArrayList<BlockPos> both = new ArrayList<>(openFarmland);
|
||||
both.addAll(openSoulsand);
|
||||
for (BlockPos pos : both) {
|
||||
boolean soulsand = openSoulsand.contains(pos);
|
||||
Optional<Rotation> rot = RotationUtils.reachableOffset(ctx.player(), pos, new Vec3d(pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5), ctx.playerController().getBlockReachDistance());
|
||||
if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, soulsand ? this::isNetherWart : this::isPlantable)) {
|
||||
baritone.getLookBehavior().updateTarget(rot.get(), true);
|
||||
if (ctx.isLookingAt(pos)) {
|
||||
baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true);
|
||||
}
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
}
|
||||
}
|
||||
for (BlockPos pos : bonemealable) {
|
||||
Optional<Rotation> rot = RotationUtils.reachable(ctx, pos);
|
||||
if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, this::isBoneMeal)) {
|
||||
baritone.getLookBehavior().updateTarget(rot.get(), true);
|
||||
if (ctx.isLookingAt(pos)) {
|
||||
baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true);
|
||||
}
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (calcFailed) {
|
||||
logDirect("Farm failed");
|
||||
onLostControl();
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
}
|
||||
|
||||
List<Goal> goalz = new ArrayList<>();
|
||||
for (BlockPos pos : toBreak) {
|
||||
goalz.add(new BuilderProcess.GoalBreak(pos));
|
||||
}
|
||||
if (baritone.getInventoryBehavior().throwaway(false, this::isPlantable)) {
|
||||
for (BlockPos pos : openFarmland) {
|
||||
goalz.add(new GoalBlock(pos.up()));
|
||||
}
|
||||
}
|
||||
if (baritone.getInventoryBehavior().throwaway(false, this::isNetherWart)) {
|
||||
for (BlockPos pos : openSoulsand) {
|
||||
goalz.add(new GoalBlock(pos.up()));
|
||||
}
|
||||
}
|
||||
if (baritone.getInventoryBehavior().throwaway(false, this::isBoneMeal)) {
|
||||
for (BlockPos pos : bonemealable) {
|
||||
goalz.add(new GoalBlock(pos));
|
||||
}
|
||||
}
|
||||
for (Entity entity : ctx.world().loadedEntityList) {
|
||||
if (entity instanceof EntityItem && entity.onGround) {
|
||||
EntityItem ei = (EntityItem) entity;
|
||||
if (PICKUP_DROPPED.contains(ei.getItem().getItem())) {
|
||||
// +0.1 because of farmland's 0.9375 dummy height lol
|
||||
goalz.add(new GoalBlock(new BlockPos(entity.posX, entity.posY + 0.1, entity.posZ)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return new PathingCommand(new GoalComposite(goalz.toArray(new Goal[0])), PathingCommandType.SET_GOAL_AND_PATH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLostControl() {
|
||||
active = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayName0() {
|
||||
return "Farming";
|
||||
}
|
||||
}
|
||||
@@ -117,7 +117,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
|
||||
}
|
||||
|
||||
// blacklist the closest block and its adjacent blocks
|
||||
public synchronized void blacklistClosest() {
|
||||
public synchronized boolean blacklistClosest() {
|
||||
List<BlockPos> newBlacklist = new ArrayList<>();
|
||||
knownLocations.stream().min(Comparator.comparingDouble(ctx.player()::getDistanceSq)).ifPresent(newBlacklist::add);
|
||||
outer:
|
||||
@@ -140,6 +140,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
|
||||
}
|
||||
logDebug("Blacklisting unreachable locations " + newBlacklist);
|
||||
blacklist.addAll(newBlacklist);
|
||||
return !newBlacklist.isEmpty();
|
||||
}
|
||||
|
||||
// safer than direct double comparison from distanceSq
|
||||
|
||||
@@ -22,16 +22,20 @@ import baritone.api.pathing.goals.*;
|
||||
import baritone.api.process.IMineProcess;
|
||||
import baritone.api.process.PathingCommand;
|
||||
import baritone.api.process.PathingCommandType;
|
||||
import baritone.api.utils.BlockUtils;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
import baritone.api.utils.Rotation;
|
||||
import baritone.api.utils.RotationUtils;
|
||||
import baritone.api.utils.input.Input;
|
||||
import baritone.cache.CachedChunk;
|
||||
import baritone.cache.ChunkPacker;
|
||||
import baritone.cache.WorldScanner;
|
||||
import baritone.pathing.movement.CalculationContext;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.utils.BaritoneProcessHelper;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockAir;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.init.Blocks;
|
||||
@@ -81,26 +85,48 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
|
||||
return null;
|
||||
}
|
||||
}
|
||||
boolean shouldCancel = calcFailed;
|
||||
if (calcFailed && !knownOreLocations.isEmpty() && Baritone.settings().blacklistClosestOnFailure.value) {
|
||||
logDirect("Unable to find any path to " + mining + ", blacklisting presumably unreachable closest instance...");
|
||||
knownOreLocations.stream().sorted(Comparator.comparingDouble(ctx.player()::getDistanceSq)).findFirst().ifPresent(blacklist::add);
|
||||
knownOreLocations.stream().min(Comparator.comparingDouble(ctx.player()::getDistanceSq)).ifPresent(blacklist::add);
|
||||
knownOreLocations.removeIf(blacklist::contains);
|
||||
calcFailed = false; // 😎
|
||||
shouldCancel = false; // 😎
|
||||
}
|
||||
if (calcFailed) {
|
||||
if (shouldCancel) {
|
||||
logDirect("Unable to find any path to " + mining + ", canceling Mine");
|
||||
cancel();
|
||||
return null;
|
||||
}
|
||||
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.value;
|
||||
List<BlockPos> curr = new ArrayList<>(knownOreLocations);
|
||||
if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain
|
||||
List<BlockPos> curr = new ArrayList<>(knownOreLocations);
|
||||
CalculationContext context = new CalculationContext(baritone, true);
|
||||
Baritone.getExecutor().execute(() -> rescan(curr, context));
|
||||
}
|
||||
if (Baritone.settings().legitMine.value) {
|
||||
addNearby();
|
||||
}
|
||||
Optional<BlockPos> shaft = curr.stream()
|
||||
.filter(pos -> pos.getX() == ctx.playerFeet().getX() && pos.getZ() == ctx.playerFeet().getZ())
|
||||
.filter(pos -> pos.getY() > ctx.playerFeet().getY())
|
||||
.filter(pos -> !(BlockStateInterface.get(ctx, pos).getBlock() instanceof BlockAir)) // after breaking a block, it takes mineGoalUpdateInterval ticks for it to actually update this list =(
|
||||
.min(Comparator.comparingDouble(ctx.player()::getDistanceSq));
|
||||
baritone.getInputOverrideHandler().clearAllKeys();
|
||||
if (shaft.isPresent()) {
|
||||
BlockPos pos = shaft.get();
|
||||
IBlockState state = baritone.bsi.get0(pos);
|
||||
if (!MovementHelper.avoidBreaking(baritone.bsi, pos.getX(), pos.getY(), pos.getZ(), state)) {
|
||||
Optional<Rotation> rot = RotationUtils.reachable(ctx, pos);
|
||||
if (rot.isPresent() && isSafeToCancel) {
|
||||
baritone.getLookBehavior().updateTarget(rot.get(), true);
|
||||
MovementHelper.switchToBestToolFor(ctx, ctx.world().getBlockState(pos));
|
||||
if (ctx.isLookingAt(pos) || ctx.playerRotations().isReallyCloseTo(rot.get())) {
|
||||
baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_LEFT, true);
|
||||
}
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
PathingCommand command = updateGoal();
|
||||
if (command == null) {
|
||||
// none in range
|
||||
@@ -177,15 +203,63 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
|
||||
knownOreLocations = locs;
|
||||
}
|
||||
|
||||
private static boolean internalMiningGoal(BlockPos pos, IPlayerContext ctx, List<BlockPos> locs) {
|
||||
// Here, BlockStateInterface is used because the position may be in a cached chunk (the targeted block is one that is kept track of)
|
||||
return locs.contains(pos) || (Baritone.settings().internalMiningAirException.value && BlockStateInterface.getBlock(ctx, pos) instanceof BlockAir);
|
||||
}
|
||||
|
||||
private static Goal coalesce(IPlayerContext ctx, BlockPos loc, List<BlockPos> locs) {
|
||||
if (!Baritone.settings().forceInternalMining.value) {
|
||||
return new GoalTwoBlocks(loc);
|
||||
return new GoalThreeBlocks(loc);
|
||||
}
|
||||
boolean upwardGoal = internalMiningGoal(loc.up(), ctx, locs);
|
||||
boolean downwardGoal = internalMiningGoal(loc.down(), ctx, locs);
|
||||
boolean doubleDownwardGoal = internalMiningGoal(loc.down(2), ctx, locs);
|
||||
if (upwardGoal == downwardGoal) { // symmetric
|
||||
if (doubleDownwardGoal) {
|
||||
// we have a checkerboard like pattern
|
||||
// this one, and the one two below it
|
||||
// therefore it's fine to path to immediately below this one, since your feet will be in the doubleDownwardGoal
|
||||
return new GoalThreeBlocks(loc);
|
||||
} else {
|
||||
// this block has nothing interesting two below, but is symmetric vertically so we can get either feet or head into it
|
||||
return new GoalTwoBlocks(loc);
|
||||
}
|
||||
}
|
||||
if (upwardGoal) {
|
||||
// downwardGoal known to be false
|
||||
// ignore the gap then potential doubleDownward, because we want to path feet into this one and head into upwardGoal
|
||||
return new GoalBlock(loc);
|
||||
}
|
||||
// upwardGoal known to be false, downwardGoal known to be true
|
||||
if (doubleDownwardGoal) {
|
||||
// this block and two below it are goals
|
||||
// path into the center of the one below, because that includes directly below this one
|
||||
return new GoalTwoBlocks(loc.down());
|
||||
}
|
||||
// upwardGoal false, downwardGoal true, doubleDownwardGoal false
|
||||
// just this block and the one immediately below, no others
|
||||
return new GoalBlock(loc.down());
|
||||
}
|
||||
|
||||
private static class GoalThreeBlocks extends GoalTwoBlocks {
|
||||
|
||||
public GoalThreeBlocks(BlockPos pos) {
|
||||
super(pos);
|
||||
}
|
||||
|
||||
// Here, BlockStateInterface is used because the position may be in a cached chunk (the targeted block is one that is kept track of)
|
||||
boolean upwardGoal = locs.contains(loc.up()) || (Baritone.settings().internalMiningAirException.value && BlockStateInterface.getBlock(ctx, loc.up()) == Blocks.AIR);
|
||||
boolean downwardGoal = locs.contains(loc.down()) || (Baritone.settings().internalMiningAirException.value && BlockStateInterface.getBlock(ctx, loc.down()) == Blocks.AIR);
|
||||
return upwardGoal == downwardGoal ? new GoalTwoBlocks(loc) : upwardGoal ? new GoalBlock(loc) : new GoalBlock(loc.down());
|
||||
@Override
|
||||
public boolean isInGoal(int x, int y, int z) {
|
||||
return x == this.x && (y == this.y || y == this.y - 1 || y == this.y - 2) && z == this.z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double heuristic(int x, int y, int z) {
|
||||
int xDiff = x - this.x;
|
||||
int yDiff = y - this.y;
|
||||
int zDiff = z - this.z;
|
||||
return GoalBlock.calculate(xDiff, yDiff < -1 ? yDiff + 2 : yDiff == -1 ? 0 : yDiff, zDiff);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<BlockPos> droppedItemsScan(List<Block> mining, World world) {
|
||||
@@ -214,24 +288,20 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
|
||||
public static List<BlockPos> searchWorld(CalculationContext ctx, List<Block> mining, int max, List<BlockPos> alreadyKnown, List<BlockPos> blacklist) {
|
||||
List<BlockPos> locs = new ArrayList<>();
|
||||
List<Block> uninteresting = new ArrayList<>();
|
||||
//long b = System.currentTimeMillis();
|
||||
for (Block m : mining) {
|
||||
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(m)) {
|
||||
// maxRegionDistanceSq 2 means adjacent directly or adjacent diagonally; nothing further than that
|
||||
locs.addAll(ctx.worldData.getCachedWorld().getLocationsOf(ChunkPacker.blockToString(m), Baritone.settings().maxCachedWorldScanCount.value, ctx.getBaritone().getPlayerContext().playerFeet().getX(), ctx.getBaritone().getPlayerContext().playerFeet().getZ(), 2));
|
||||
locs.addAll(ctx.worldData.getCachedWorld().getLocationsOf(BlockUtils.blockToString(m), Baritone.settings().maxCachedWorldScanCount.value, ctx.getBaritone().getPlayerContext().playerFeet().getX(), ctx.getBaritone().getPlayerContext().playerFeet().getZ(), 2));
|
||||
} else {
|
||||
uninteresting.add(m);
|
||||
}
|
||||
}
|
||||
locs = prune(ctx, locs, mining, max, blacklist);
|
||||
//System.out.println("Scan of cached chunks took " + (System.currentTimeMillis() - b) + "ms");
|
||||
if (locs.isEmpty()) {
|
||||
if (locs.isEmpty() || (Baritone.settings().extendCacheOnThreshold.value && locs.size() < max)) {
|
||||
uninteresting = mining;
|
||||
}
|
||||
if (!uninteresting.isEmpty()) {
|
||||
//long before = System.currentTimeMillis();
|
||||
locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(ctx.getBaritone().getPlayerContext(), uninteresting, max, 10, 32)); // maxSearchRadius is NOT sq
|
||||
//System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms");
|
||||
}
|
||||
locs.addAll(alreadyKnown);
|
||||
return prune(ctx, locs, mining, max, blacklist);
|
||||
@@ -302,7 +372,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
|
||||
|
||||
@Override
|
||||
public void mineByName(int quantity, String... blocks) {
|
||||
mine(quantity, blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(ChunkPacker::stringToBlockRequired).toArray(Block[]::new));
|
||||
mine(quantity, blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(BlockUtils::stringToBlockRequired).toArray(Block[]::new));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,6 +22,7 @@ import baritone.api.event.events.TickEvent;
|
||||
import baritone.api.event.listener.AbstractGameEventListener;
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
import baritone.api.pathing.goals.GoalBlock;
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiMainMenu;
|
||||
|
||||
@@ -19,6 +19,7 @@ package baritone.utils;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.process.IBaritoneProcess;
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
|
||||
public abstract class BaritoneProcessHelper implements IBaritoneProcess, Helper {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package baritone.utils;
|
||||
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumHand;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package baritone.utils;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumHand;
|
||||
|
||||
@@ -87,7 +87,6 @@ public class GuiClick extends GuiScreen {
|
||||
clickStart = null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) {
|
||||
clickStart = currentMouseOver;
|
||||
@@ -120,8 +119,6 @@ public class GuiClick extends GuiScreen {
|
||||
GlStateManager.disableBlend();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public Vec3d toWorld(double x, double y, double z) {
|
||||
|
||||
@@ -23,6 +23,7 @@ import baritone.api.event.events.RenderEvent;
|
||||
import baritone.api.pathing.calc.IPath;
|
||||
import baritone.api.pathing.goals.*;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.api.utils.interfaces.IGoalRenderPos;
|
||||
import baritone.behavior.PathingBehavior;
|
||||
import baritone.pathing.path.PathExecutor;
|
||||
@@ -83,17 +84,22 @@ public final class PathRenderer implements Helper {
|
||||
if (goal != null && Baritone.settings().renderGoal.value) {
|
||||
drawDankLitGoalBox(renderView, goal, partialTicks, Baritone.settings().colorGoalBox.value);
|
||||
}
|
||||
|
||||
if (!Baritone.settings().renderPath.value) {
|
||||
return;
|
||||
}
|
||||
PathExecutor current = behavior.getCurrent(); // this should prevent most race conditions?
|
||||
PathExecutor next = behavior.getNext(); // like, now it's not possible for current!=null to be true, then suddenly false because of another thread
|
||||
if (current != null && Baritone.settings().renderSelectionBoxes.value) {
|
||||
drawManySelectionBoxes(renderView, current.toBreak(), Baritone.settings().colorBlocksToBreak.value);
|
||||
drawManySelectionBoxes(renderView, current.toPlace(), Baritone.settings().colorBlocksToPlace.value);
|
||||
drawManySelectionBoxes(renderView, current.toWalkInto(), Baritone.settings().colorBlocksToWalkInto.value);
|
||||
}
|
||||
|
||||
//drawManySelectionBoxes(player, Collections.singletonList(behavior.pathStart()), partialTicks, Color.WHITE);
|
||||
//long start = System.nanoTime();
|
||||
|
||||
|
||||
PathExecutor current = behavior.getCurrent(); // this should prevent most race conditions?
|
||||
PathExecutor next = behavior.getNext(); // like, now it's not possible for current!=null to be true, then suddenly false because of another thread
|
||||
|
||||
// Render the current path, if there is one
|
||||
if (current != null && current.getPath() != null) {
|
||||
int renderBegin = Math.max(current.getPosition() - 3, 0);
|
||||
@@ -104,11 +110,6 @@ public final class PathRenderer implements Helper {
|
||||
}
|
||||
|
||||
//long split = System.nanoTime();
|
||||
if (current != null) {
|
||||
drawManySelectionBoxes(renderView, current.toBreak(), Baritone.settings().colorBlocksToBreak.value);
|
||||
drawManySelectionBoxes(renderView, current.toPlace(), Baritone.settings().colorBlocksToPlace.value);
|
||||
drawManySelectionBoxes(renderView, current.toWalkInto(), Baritone.settings().colorBlocksToWalkInto.value);
|
||||
}
|
||||
|
||||
// If there is a path calculation currently running, render the path calculation process
|
||||
behavior.getInProgress().ifPresent(currentlyRunning -> {
|
||||
@@ -175,7 +176,7 @@ public final class PathRenderer implements Helper {
|
||||
}
|
||||
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], alpha);
|
||||
}
|
||||
drawLine(player, x1, y1, z1, x2, y2, z2);
|
||||
drawLine(x1, y1, z1, x2, y2, z2);
|
||||
tessellator.draw();
|
||||
}
|
||||
if (Baritone.settings().renderPathIgnoreDepth.value) {
|
||||
@@ -187,7 +188,7 @@ public final class PathRenderer implements Helper {
|
||||
GlStateManager.disableBlend();
|
||||
}
|
||||
|
||||
public static void drawLine(Entity player, double bp1x, double bp1y, double bp1z, double bp2x, double bp2y, double bp2z) {
|
||||
public static void drawLine(double bp1x, double bp1y, double bp1z, double bp2x, double bp2y, double bp2z) {
|
||||
double d0 = mc.getRenderManager().viewerPosX;
|
||||
double d1 = mc.getRenderManager().viewerPosY;
|
||||
double d2 = mc.getRenderManager().viewerPosZ;
|
||||
|
||||
@@ -92,8 +92,8 @@ public class PathingControlManager implements IPathingControlManager {
|
||||
p.secretInternalSetGoal(null);
|
||||
return;
|
||||
}
|
||||
if (inControlThisTick != inControlLastTick && command.commandType != PathingCommandType.REQUEST_PAUSE) {
|
||||
// if control has changed, and the new process wants to do something
|
||||
if (inControlThisTick != inControlLastTick && command.commandType != PathingCommandType.REQUEST_PAUSE && inControlLastTick != null && !inControlLastTick.isTemporary()) {
|
||||
// if control has changed from a real process to another real process, and the new process wants to do something
|
||||
p.cancelSegmentIfSafe();
|
||||
// get rid of the in progress stuff from the last process
|
||||
}
|
||||
@@ -200,10 +200,10 @@ public class PathingControlManager implements IPathingControlManager {
|
||||
PathingCommand exec = proc.onTick(Objects.equals(proc, inControlLastTick) && baritone.getPathingBehavior().calcFailedLastTick(), baritone.getPathingBehavior().isSafeToCancel());
|
||||
if (exec == null) {
|
||||
if (proc.isActive()) {
|
||||
throw new IllegalStateException(proc.displayName() + " returned null PathingCommand");
|
||||
throw new IllegalStateException(proc.displayName() + " actively returned null PathingCommand");
|
||||
}
|
||||
proc.onLostControl();
|
||||
} else {
|
||||
// no need to call onLostControl; they are reporting inactive.
|
||||
} else if (exec.commandType != PathingCommandType.DEFER) {
|
||||
inControlThisTick = proc;
|
||||
if (!proc.isTemporary()) {
|
||||
iterator.forEachRemaining(IBaritoneProcess::onLostControl);
|
||||
|
||||
@@ -19,6 +19,7 @@ package baritone.utils.pathing;
|
||||
|
||||
import baritone.api.pathing.calc.IPath;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
import baritone.pathing.movement.CalculationContext;
|
||||
import it.unimi.dsi.fastutil.longs.Long2DoubleOpenHashMap;
|
||||
@@ -31,7 +32,7 @@ public final class Favoring {
|
||||
for (Avoidance avoid : Avoidance.create(ctx)) {
|
||||
avoid.applySpherical(favorings);
|
||||
}
|
||||
System.out.println("Favoring size: " + favorings.size());
|
||||
Helper.HELPER.logDebug("Favoring size: " + favorings.size());
|
||||
}
|
||||
|
||||
public Favoring(IPath previous, CalculationContext context) { // create one just from previous path, no mob avoidances
|
||||
|
||||
@@ -19,10 +19,10 @@ package baritone.utils.player;
|
||||
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.cache.IWorldData;
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
import baritone.api.utils.IPlayerController;
|
||||
import baritone.api.utils.RayTraceUtils;
|
||||
import baritone.utils.Helper;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
package baritone.utils.player;
|
||||
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.api.utils.IPlayerController;
|
||||
import baritone.utils.Helper;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
Reference in New Issue
Block a user