Compare commits

...

93 Commits

Author SHA1 Message Date
Leijurv 2ee119fc64 v1.2.6 2019-04-22 20:41:27 -07:00
Leijurv 83265fcb54 add blocks to avoid breaking, fixes #368 2019-04-22 19:52:04 -07:00
Leijurv e8b4f4d2b6 make the completion check a setting 2019-04-22 15:33:40 -07:00
Leijurv 714c6773c3 explain what invert means 2019-04-22 14:51:07 -07:00
Leijurv 2fac594315 say if its inverted 2019-04-22 14:36:12 -07:00
Leijurv 4bec49de5b filter explored chunks with json 2019-04-22 14:34:31 -07:00
Leijurv 4eaa6e20c3 thanks for the tip cda 2019-04-22 09:46:26 -07:00
Leijurv 315cc26525 Merge branch 'backfill-2' 2019-04-21 21:42:11 -08:00
Brady 794a761243 Remove redundant Arrays.asList call 2019-04-21 17:05:33 -05:00
Leijurv 5da14fcb3f fix 2019-04-20 15:35:11 -07:00
Brady 1047d4ade9 Babbaj doesn't know how to convert imperative shitcode into a regex
and leijurv doesn't know how to verify that the regex reflects the original behavior
im literally raging
2019-04-20 17:26:41 -05:00
Brady 0b8fa3ffe3 Fix the scuffed usage of LinkedList and ArrayList for list setting types 2019-04-20 17:10:35 -05:00
Leijurv 498e4e2d6c replant nether wart setting 2019-04-20 11:03:59 -07:00
Leijurv 850c414e8f Merge pull request #393 from CDAGaming/pr_changes
[Change] Add Block Avoidance Settings
2019-04-20 11:03:39 -07:00
cdagaming d5a8ed5cb1 [Change] More Suggested changes 2019-04-20 12:32:35 -05:00
cdagaming dd8406c39a [Fix] Remove unused Settings 2019-04-20 12:13:28 -05:00
cdagaming 13469053b9 [Change] Suggested Changes 2019-04-20 12:11:46 -05:00
cdagaming c4c85b4f49 [Change] Add Block Avoidance Settings
Fixes #392
2019-04-20 12:04:07 -05:00
Leijurv af0c3bbd5c just one is not good enough tbh 2019-04-19 21:02:58 -07:00
Leijurv 2fcf9ace64 exploration chunk offset 2019-04-19 15:10:16 -07:00
Leijurv 47e1c67bd8 fix that null exception 2019-04-19 14:20:00 -07:00
Leijurv 7e3aa6efdd Merge branch 'master' into backfill-2 2019-04-19 10:59:21 -07:00
Leijurv 7a2f26ef62 replace scuffed ternary with commented if 2019-04-18 10:36:20 -07:00
Leijurv b64154e3b3 meme for cached blocks that arent packed yet 2019-04-17 23:25:55 -07:00
Leijurv 26256e7155 mine is now MUCH more epic 2019-04-17 22:17:09 -07:00
Leijurv 6599736e00 fix that reference 2019-04-17 20:23:36 -07:00
Leijurv 343bb20bd8 fix weird cache behavior at chunk edge 2019-04-17 20:02:02 -07:00
Leijurv 518fa1c74d reformat all files 2019-04-17 19:49:04 -07:00
Leijurv 0b72a8b4b3 fix overshoot 2019-04-17 19:46:25 -07:00
Leijurv c013d1e0d9 fix various toxic clouds 2019-04-17 18:10:47 -07:00
Leijurv fe51220e3c this might help 2019-04-16 23:19:55 -07:00
Leijurv 44d757347b fix unable to move while paused 2019-04-16 22:43:33 -07:00
Leijurv c136182e17 add option to manually blacklist closest 2019-04-16 18:04:43 -07:00
Leijurv a1a9b4e6b9 allow spaces 2019-04-16 10:25:32 -07:00
Leijurv f49df63183 that can never be null 2019-04-16 10:20:23 -07:00
Leijurv 96414b37f3 whoops this was fixed monthhs ago 2019-04-15 18:14:20 -07:00
Leijurv 544168ff45 Merge branch 'farm' 2019-04-15 17:28:13 -07:00
Leijurv e0a618a791 epic farm 2019-04-15 17:12:20 -07:00
Leijurv 3333797144 fix region pruning 2019-04-14 10:06:50 -07:00
Leijurv f7f003c0f9 farm 2019-04-13 19:05:54 -07:00
Leijurv 236d02cb47 add a way to pause builder 2019-04-13 08:36:14 -07:00
Leijurv 6e97fe2210 dont crash when exiting a world 2019-04-12 21:48:02 -07:00
Leijurv 6741666c24 Merge branch 'master' into backfill-2 2019-04-12 17:43:01 -07:00
Leijurv fcadf68c90 cool tunnel feature and various fixes 2019-04-12 17:42:50 -07:00
Leijurv 65cd6a92d3 allow saving enumfacing value 2019-04-11 16:42:04 -07:00
Leijurv a09bb0d538 build repeat option 2019-04-11 16:36:20 -07:00
Leijurv 2bf475d840 build in layers test 2019-04-11 15:17:26 -07:00
Leijurv 76cdaaace6 add todo 2019-04-10 23:45:52 -07:00
Leijurv ce59ef559f backport important world scanner fixes 2019-04-09 19:35:43 -07:00
Leijurv fc3f183dce actually don't render the boxes if renderpath is false 2019-04-09 08:45:30 -07:00
Leijurv 6b6eea2d8c add renderSelectionBoxes, fixes #378 2019-04-08 20:32:47 -08:00
Leijurv e54652941b codacy 2019-04-07 17:44:23 -07:00
Leijurv 867c01ff86 crucial performance optimization 2019-04-06 21:50:22 -08:00
Leijurv 87a9e67ba8 dont reassign arg 2019-04-05 11:59:28 -07:00
Leijurv bf076f6246 privatize 2019-04-04 20:51:02 -08:00
Leijurv 75b54dfaec nullpointer is confusing 2019-04-03 23:19:32 -07:00
Leijurv 71a2219b07 move fields to the top 2019-04-02 21:40:33 -08:00
Leijurv ccc3de2d7c dawn of the 8th month 2019-04-01 23:30:33 -07:00
Leijurv af11e64cec combine nested 2019-03-31 20:22:17 -08:00
Leijurv 2c3dc5d6b1 add plea 2019-03-30 23:23:12 -07:00
Leijurv 71482cc984 explain for brainlets 2019-03-29 23:10:19 -07:00
Leijurv 3329db1dae these show the exact same info; remove one 2019-03-28 23:01:14 -07:00
Leijurv 926e2d5620 add resuming to builder, fixes #371 2019-03-27 17:32:02 -07:00
Leijurv d2de8828e7 did this 2019-03-26 23:01:07 -07:00
Leijurv 9fcae6560e better feature branch example 2019-03-25 21:03:19 -08:00
Leijurv 2e8fdd43ee no flowing 2019-03-24 13:53:19 -07:00
Leijurv 27e39c8083 update badges 2019-03-24 13:50:50 -07:00
Leijurv a8f373d568 fine; assumewalkonlava 2019-03-24 13:07:08 -07:00
Leijurv 71491a7922 blank space 2019-03-23 22:17:40 -08:00
Leijurv 170c2d35c2 perhaps updating debian will help 2019-03-22 21:17:20 -07:00
Leijurv bc49b2d5ba add allowDownward, fixes #369 2019-03-22 15:50:23 -07:00
Leijurv f58b6b41cb second attempt at backfill 2019-03-22 15:45:34 -07:00
Leijurv ac1ac50158 add some builder commands to usage 2019-03-22 14:36:21 -07:00
Leijurv d4103a924d add two new awesome badges 2019-03-21 16:58:31 -07:00
Leijurv bd64f73842 fix disconnect on arrival not firing for custom goal process 2019-03-21 15:44:20 -07:00
Leijurv cac653ddd9 little cleanup 2019-03-20 23:06:14 -07:00
Leijurv 04ff365890 what about if i delete two (2) empty lines 2019-03-20 23:03:06 -07:00
Leijurv 54ed6ce5a5 crucial code formatting 2019-03-20 22:55:40 -07:00
Brady 32ac46c8a9 Update PULL_REQUEST_TEMPLATE.md 2019-03-19 21:26:58 -05:00
Brady 7ab2cd2a45 Update ISSUE_TEMPLATE.md 2019-03-19 21:26:47 -05:00
Brady a07fae6cdd Update Code of Conduct to include templates 2019-03-19 21:25:58 -05:00
babbaj 3f6af51713 Create PULL_REQUEST_TEMPLATE.md 2019-03-19 21:23:05 -05:00
babbaj 8c4e778506 Create ISSUE_TEMPLATE.md 2019-03-19 21:23:05 -05:00
Leijurv 65902d556e v1.2.5 2019-03-19 18:22:22 -07:00
Leijurv aada9731a6 more resiliency to invalid cache files 2019-03-19 18:10:53 -07:00
Leijurv 49658078b9 trapdoors cant be passed vertically in either state, thanks plutie 2019-03-18 22:38:06 -07:00
Leijurv bcd097c6cb we can cancel calc even if not safe to cancel pathing 2019-03-17 22:40:11 -08:00
Leijurv cfec67f1f9 wording 2019-03-16 23:23:20 -07:00
Leijurv aaaf0f8839 hey so what if we didnt do that 2019-03-15 16:40:15 -07:00
Leijurv ee83471bf6 fix being unable to place or pick up water buckets 2019-03-15 14:26:38 -07:00
Leijurv 610fe6439f fix getting permanently stuck on vines 2019-03-15 14:25:43 -07:00
Leijurv bd1dcff385 allow ties for closest to explore to 2019-03-14 14:52:51 -07:00
Leijurv 226ede7ba2 crucial 2019-03-13 19:23:28 -07:00
75 changed files with 1664 additions and 363 deletions
+1
View File
@@ -0,0 +1 @@
<!-- No UwU's or OwO's allowed -->
+1
View File
@@ -0,0 +1 @@
<!-- No UwU's or OwO's allowed -->
+5
View File
@@ -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, permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful. 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 ## Scope
This Code of Conduct applies both within project spaces and in public spaces This Code of Conduct applies both within project spaces and in public spaces
+5 -6
View File
@@ -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 ENV DEBIAN_FRONTEND noninteractive
RUN apt update -y RUN apt update -y
RUN apt install --target-release jessie-backports \ RUN apt install \
openjdk-8-jdk \ openjdk-8-jdk \
ca-certificates-java \
--assume-yes --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 COPY . /code
@@ -21,4 +20,4 @@ WORKDIR /code
# source: https://github.com/tectonicus/tectonicus/issues/60#issuecomment-154239173 # source: https://github.com/tectonicus/tectonicus/issues/60#issuecomment-154239173
RUN dpkg -i scripts/xvfb_1.16.4-1_amd64.deb RUN dpkg -i scripts/xvfb_1.16.4-1_amd64.deb
RUN ./gradlew build RUN ./gradlew build
+4 -3
View File
@@ -13,15 +13,16 @@
![Code size](https://img.shields.io/github/languages/code-size/cabaletta/baritone.svg) ![Code size](https://img.shields.io/github/languages/code-size/cabaletta/baritone.svg)
![GitHub repo size](https://img.shields.io/github/repo-size/cabaletta/baritone.svg) ![GitHub repo size](https://img.shields.io/github/repo-size/cabaletta/baritone.svg)
![](https://tokei.rs/b1/github/cabaletta/baritone?category=code) ![](https://tokei.rs/b1/github/cabaletta/baritone?category=code)
![](https://tokei.rs/b1/github/cabaletta/baritone?category=files)
[![Minecraft](https://img.shields.io/badge/MC-1.12.2-green.svg)](https://minecraft.gamepedia.com/1.12.2) [![Minecraft](https://img.shields.io/badge/MC-1.12.2-green.svg)](https://minecraft.gamepedia.com/1.12.2)
[![GitHub contributors](https://img.shields.io/github/contributors/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/graphs/contributors/) [![GitHub contributors](https://img.shields.io/github/contributors/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/graphs/contributors/)
[![GitHub commits](https://img.shields.io/github/commits-since/cabaletta/baritone/v1.0.0.svg)](https://github.com/cabaletta/baritone/commit/) [![GitHub commits](https://img.shields.io/github/commits-since/cabaletta/baritone/v1.0.0.svg)](https://github.com/cabaletta/baritone/commit/)
[![Impact integration](https://img.shields.io/badge/Impact%20integration-v1.2.3-brightgreen.svg)](https://impactdevelopment.github.io/) [![Impact integration](https://img.shields.io/badge/Impact%20integration-v1.2.5%20/%20v1.3.0-brightgreen.svg)](https://impactdevelopment.github.io/)
[![WWE integration](https://img.shields.io/badge/WWE%20%22integration%22-master%3F-green.svg)](https://wweclient.com/) [![WWE integration](https://img.shields.io/badge/WWE%20%22integration%22-master%3F-green.svg)](https://wweclient.com/)
[![KAMI integration](https://img.shields.io/badge/KAMI%20integration-v1.0.0-red.svg)](https://github.com/zeroeightysix/KAMI/) [![KAMI integration](https://img.shields.io/badge/KAMI%20integration-v1.0.0-red.svg)](https://github.com/zeroeightysix/KAMI/)
[![Future integration](https://img.shields.io/badge/Future%20integration-Soon™%3F%3F%3F-red.svg)](https://futureclient.net/) [![Future integration](https://img.shields.io/badge/Future%20integration-Soon™%3F%3F%3F-red.svg)](https://futureclient.net/)
[![ForgeHax integration](https://img.shields.io/badge/ForgeHax%20integration-Soon™-red.svg)](https://github.com/fr1kin/ForgeHax) [![ForgeHax integration](https://img.shields.io/badge/ForgeHax%20integration-Soon™-red.svg)](https://github.com/fr1kin/ForgeHax)
[![forthebadge](https://forthebadge.com/images/badges/built-with-swag.svg)](http://forthebadge.com)
[![forthebadge](https://forthebadge.com/images/badges/mom-made-pizza-rolls.svg)](http://forthebadge.com)
A Minecraft pathfinder bot. 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/), 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). 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 1Leijurv3DWTrGAfmmiTphjhXLvQiHg7K2
+1 -1
View File
@@ -1,7 +1,7 @@
# Installation # Installation
## Prebuilt official releases ## 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) Link to the releases page: [Releases](https://github.com/cabaletta/baritone/releases)
+2 -4
View File
@@ -34,7 +34,7 @@ Some common examples:
- `cancel` or `stop` to stop everything - `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) - `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.) - `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). - `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. - `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). - `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 - `render` to rerender the world in case `renderCachedChunks` is being glitchy
- `version` to get the version of Baritone you're running - `version` to get the version of Baritone you're running
- `damn` daniel - `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). 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 # 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? ## Why doesn't Baritone respond to any of my chat commands?
This could be one of many things. This could be one of many things.
+1 -1
View File
@@ -16,7 +16,7 @@
*/ */
group 'baritone' group 'baritone'
version '1.2.4' version '1.2.6'
buildscript { buildscript {
repositories { repositories {
+2
View File
@@ -21,6 +21,8 @@
-keep class baritone.BaritoneProvider -keep class baritone.BaritoneProvider
-keep class baritone.api.IBaritoneProvider -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 # setting names are reflected from field names, so keep field names
-keepclassmembers class baritone.api.Settings { -keepclassmembers class baritone.api.Settings {
public <fields>; public <fields>;
+14
View File
@@ -71,6 +71,18 @@ public interface IBaritone {
*/ */
IBuilderProcess getBuilderProcess(); 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 * @return The {@link ICustomGoalProcess} instance
* @see ICustomGoalProcess * @see ICustomGoalProcess
@@ -115,4 +127,6 @@ public interface IBaritone {
* @see IEventBus * @see IEventBus
*/ */
IEventBus getGameEventHandler(); IEventBus getGameEventHandler();
void openClick();
} }
+109 -8
View File
@@ -18,13 +18,18 @@
package baritone.api; package baritone.api;
import baritone.api.utils.SettingsUtil; import baritone.api.utils.SettingsUtil;
import baritone.api.utils.TypeUtils;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import java.awt.*; import java.awt.*;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*; import java.util.*;
import java.util.List; import java.util.List;
import java.util.function.Consumer; 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 * 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); public final Setting<Double> blockPlacementPenalty = new Setting<>(20D);
@@ -91,6 +98,11 @@ public final class Settings {
*/ */
public final Setting<Boolean> assumeWalkOnWater = new Setting<>(false); 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. * 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 * If true, parkour is allowed to make jumps when standing on blocks at the maximum height, so player feet is y=256
* <p> * <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); public final Setting<Boolean> allowJumpAt256 = new Setting<>(false);
@@ -121,15 +133,37 @@ public final class Settings {
*/ */
public final Setting<Boolean> allowDiagonalDescend = new Setting<>(false); 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.) * 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( public final Setting<List<Item>> acceptableThrowawayItems = new Setting<>(new ArrayList<>(Arrays.asList(
Item.getItemFromBlock(Blocks.DIRT), Item.getItemFromBlock(Blocks.DIRT),
Item.getItemFromBlock(Blocks.COBBLESTONE), 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 * 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. * 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 * On save, delete from RAM any cached regions that are more than 1024 blocks away from the player
* <p> * <p>
* Temporarily disabled * Temporarily disabled
* <p>
* Temporarily reenabled
* *
* @see <a href="https://github.com/cabaletta/baritone/issues/248">Issue #248</a> * @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) * Remember the contents of containers (chests, echests, furnaces)
@@ -398,6 +434,11 @@ public final class Settings {
*/ */
public final Setting<Boolean> containerMemory = new Setting<>(false); 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 * Print all the debug messages to chat
*/ */
@@ -424,6 +465,11 @@ public final class Settings {
*/ */
public final Setting<Boolean> renderGoal = new Setting<>(true); 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 * Ignore depth when rendering the goal
*/ */
@@ -547,6 +593,45 @@ public final class Settings {
*/ */
public final Setting<Boolean> exploreForBlocks = new Setting<>(true); 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)? * 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); 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 * 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 * -1 to disable
@@ -719,11 +810,12 @@ public final class Settings {
*/ */
public final List<Setting<?>> allSettings; public final List<Setting<?>> allSettings;
public final Map<Setting<?>, Type> settingTypes;
public final class Setting<T> { public final class Setting<T> {
public T value; public T value;
public final T defaultValue; public final T defaultValue;
private String name; private String name;
private final Class<T> klass;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private Setting(T value) { private Setting(T value) {
@@ -732,7 +824,6 @@ public final class Settings {
} }
this.value = value; this.value = value;
this.defaultValue = value; this.defaultValue = value;
this.klass = (Class<T>) value.getClass();
} }
/** /**
@@ -750,7 +841,8 @@ public final class Settings {
} }
public Class<T> getValueClass() { public Class<T> getValueClass() {
return klass; // noinspection unchecked
return (Class<T>) TypeUtils.resolveBaseClass(getType());
} }
@Override @Override
@@ -764,14 +856,21 @@ public final class Settings {
public void reset() { public void reset() {
value = defaultValue; value = defaultValue;
} }
public final Type getType() {
return settingTypes.get(this);
}
} }
// here be dragons // here be dragons
Settings() { Settings() {
Field[] temp = getClass().getFields(); Field[] temp = getClass().getFields();
HashMap<String, Setting<?>> tmpByName = new HashMap<>();
Map<String, Setting<?>> tmpByName = new HashMap<>();
List<Setting<?>> tmpAll = new ArrayList<>(); List<Setting<?>> tmpAll = new ArrayList<>();
Map<Setting<?>, Type> tmpSettingTypes = new HashMap<>();
try { try {
for (Field field : temp) { for (Field field : temp) {
if (field.getType().equals(Setting.class)) { if (field.getType().equals(Setting.class)) {
@@ -784,6 +883,7 @@ public final class Settings {
} }
tmpByName.put(name, setting); tmpByName.put(name, setting);
tmpAll.add(setting); tmpAll.add(setting);
tmpSettingTypes.put(setting, ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]);
} }
} }
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
@@ -791,6 +891,7 @@ public final class Settings {
} }
byLowerName = Collections.unmodifiableMap(tmpByName); byLowerName = Collections.unmodifiableMap(tmpByName);
allSettings = Collections.unmodifiableList(tmpAll); allSettings = Collections.unmodifiableList(tmpAll);
settingTypes = Collections.unmodifiableMap(tmpSettingTypes);
} }
@SuppressWarnings("unchecked") @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. * A behavior is simply a type that is able to listen to events.
* *
* @see IGameEventListener
*
* @author Brady * @author Brady
* @see IGameEventListener
* @since 9/23/2018 * @since 9/23/2018
*/ */
public interface IBehavior extends AbstractGameEventListener {} public interface IBehavior extends AbstractGameEventListener {}
@@ -80,6 +80,13 @@ public interface IPathingBehavior extends IBehavior {
*/ */
boolean cancelEverything(); 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. * Returns the current path, from the current path executor, if there is one.
* *
+2
View File
@@ -81,4 +81,6 @@ public interface ICachedWorld {
* in a new thread by default. * in a new thread by default.
*/ */
void save(); void save();
} }
@@ -15,9 +15,8 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>. * 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 net.minecraft.util.math.BlockPos;
import java.util.Date; import java.util.Date;
@@ -47,7 +46,7 @@ public class Waypoint implements IWaypoint {
* @param location The waypoint location * @param location The waypoint location
* @param creationTimestamp When the waypoint was created * @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.name = name;
this.tag = tag; this.tag = tag;
this.location = location; this.location = location;
@@ -61,6 +61,6 @@ public class GoalNear implements Goal, IGoalRenderPos {
", y=" + y + ", y=" + y +
", z=" + z + ", z=" + z +
", rangeSq=" + rangeSq + ", 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 * The X block position of this goal
*/ */
private final int x; protected final int x;
/** /**
* The Y block position of this goal * The Y block position of this goal
*/ */
private final int y; protected final int y;
/** /**
* The Z block position of this goal * The Z block position of this goal
*/ */
private final int z; protected final int z;
public GoalTwoBlocks(BlockPos pos) { public GoalTwoBlocks(BlockPos pos) {
this(pos.getX(), pos.getY(), pos.getZ()); this(pos.getX(), pos.getY(), pos.getZ());
@@ -18,6 +18,8 @@
package baritone.api.process; package baritone.api.process;
import baritone.api.utils.ISchematic; import baritone.api.utils.ISchematic;
import net.minecraft.client.Minecraft;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i; import net.minecraft.util.math.Vec3i;
import java.io.File; 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 * @return Whether or not the schematic was able to load from file
*/ */
boolean build(String name, File schematic, Vec3i origin); 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);
} }
@@ -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;
}
@@ -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 { public interface IGetToBlockProcess extends IBaritoneProcess {
void getToBlock(Block block); void getToBlock(Block block);
boolean blacklistClosest();
} }
@@ -51,5 +51,10 @@ public enum PathingCommandType {
* <p> * <p>
* Cancel the current path if the goals are not equal * 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
} }
@@ -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/>. * 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.Settings;
import baritone.api.behavior.IPathingBehavior;
import baritone.api.cache.IRememberedInventory; import baritone.api.cache.IRememberedInventory;
import baritone.api.cache.IWaypoint; import baritone.api.cache.IWaypoint;
import baritone.api.cache.Waypoint;
import baritone.api.event.events.ChatEvent; import baritone.api.event.events.ChatEvent;
import baritone.api.event.listener.AbstractGameEventListener;
import baritone.api.pathing.goals.*; import baritone.api.pathing.goals.*;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.process.IBaritoneProcess; import baritone.api.process.IBaritoneProcess;
import baritone.api.utils.BetterBlockPos; import baritone.api.process.ICustomGoalProcess;
import baritone.api.utils.SettingsUtil; import baritone.api.process.IGetToBlockProcess;
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 net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ChunkProviderClient; import net.minecraft.client.multiplayer.ChunkProviderClient;
@@ -45,11 +39,10 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.Chunk;
import java.nio.file.Path;
import java.util.*; 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 = private static final String HELP_MSG =
"baritone - Output settings into chat\n" + "baritone - Output settings into chat\n" +
@@ -83,21 +76,26 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
private static final String COMMAND_PREFIX = "#"; private static final String COMMAND_PREFIX = "#";
public ExampleBaritoneControl(Baritone baritone) { public final IBaritone baritone;
super(baritone); public final IPlayerContext ctx;
public ExampleBaritoneControl(IBaritone baritone) {
this.baritone = baritone;
this.ctx = baritone.getPlayerContext();
baritone.getGameEventHandler().registerEventListener(this);
} }
@Override @Override
public void onSendChatMessage(ChatEvent event) { public void onSendChatMessage(ChatEvent event) {
String msg = event.getMessage(); 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()))) { if (!runCommand(msg.substring(COMMAND_PREFIX.length()))) {
logDirect("Invalid command"); logDirect("Invalid command");
} }
event.cancel(); // always cancel if using prefixControl event.cancel(); // always cancel if using prefixControl
return; return;
} }
if (!Baritone.settings().chatControl.value && !Baritone.settings().removePrefix.value) { if (!BaritoneAPI.getSettings().chatControl.value && !BaritoneAPI.getSettings().removePrefix.value) {
return; return;
} }
if (runCommand(msg)) { 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 =) 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 String msg = msg0.toLowerCase(Locale.US).trim(); // don't reassign the argument LOL
PathingBehavior pathingBehavior = baritone.getPathingBehavior(); IPathingBehavior pathingBehavior = baritone.getPathingBehavior();
CustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess(); ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
List<Settings.Setting<Boolean>> toggleable = Baritone.settings().getAllValuesByType(Boolean.class); List<Settings.Setting<Boolean>> toggleable = BaritoneAPI.getSettings().getAllValuesByType(Boolean.class);
for (Settings.Setting<Boolean> setting : toggleable) { for (Settings.Setting<Boolean> setting : toggleable) {
if (msg.equalsIgnoreCase(setting.getName())) { if (msg.equalsIgnoreCase(setting.getName())) {
setting.value ^= true; setting.value ^= true;
logDirect("Toggled " + setting.getName() + " to " + setting.value); logDirect("Toggled " + setting.getName() + " to " + setting.value);
SettingsUtil.save(Baritone.settings()); SettingsUtil.save(BaritoneAPI.getSettings());
return true; return true;
} }
} }
if (msg.equals("baritone") || msg.equals("modifiedsettings") || msg.startsWith("settings m") || msg.equals("modified")) { 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:"); 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()); logDirect(setting.toString());
} }
return true; return true;
@@ -130,15 +128,15 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
try { try {
int page = Integer.parseInt(rest.trim()); int page = Integer.parseInt(rest.trim());
int min = page * 10; 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) + ":"); logDirect("Settings " + min + " to " + (max - 1) + ":");
for (int i = min; i < max; i++) { 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 } catch (Exception ex) { // NumberFormatException | ArrayIndexOutOfBoundsException and probably some others I'm forgetting lol
ex.printStackTrace(); ex.printStackTrace();
logDirect("All settings:"); logDirect("All settings:");
for (Settings.Setting<?> setting : Baritone.settings().allSettings) { for (Settings.Setting<?> setting : BaritoneAPI.getSettings().allSettings) {
logDirect(setting.toString()); logDirect(setting.toString());
} }
logDirect("To get one page of ten settings at a time, do settings <num>"); 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(" ")) { if (msg.contains(" ")) {
String settingName = msg.substring(0, msg.indexOf(' ')); String settingName = msg.substring(0, msg.indexOf(' '));
String settingValue = msg.substring(msg.indexOf(' ') + 1); 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 (setting != null) {
if (settingValue.equals("reset")) { if (settingValue.equals("reset")) {
logDirect("Resetting setting " + settingName + " to default value."); logDirect("Resetting setting " + settingName + " to default value.");
setting.reset(); setting.reset();
} else { } else {
try { try {
SettingsUtil.parseAndApply(Baritone.settings(), settingName, settingValue); SettingsUtil.parseAndApply(BaritoneAPI.getSettings(), settingName, settingValue);
} catch (Exception ex) { } catch (Exception ex) {
logDirect("Unable to parse setting"); logDirect("Unable to parse setting");
return true; return true;
} }
} }
SettingsUtil.save(Baritone.settings()); SettingsUtil.save(BaritoneAPI.getSettings());
logDirect(setting.toString()); logDirect(setting.toString());
return true; return true;
} }
} }
if (Baritone.settings().byLowerName.containsKey(msg)) { if (BaritoneAPI.getSettings().byLowerName.containsKey(msg)) {
Settings.Setting<?> setting = Baritone.settings().byLowerName.get(msg); Settings.Setting<?> setting = BaritoneAPI.getSettings().byLowerName.get(msg);
logDirect(setting.toString()); logDirect(setting.toString());
return true; return true;
} }
@@ -209,7 +207,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
} }
return true; return true;
} }
if (msg.equals("fullpath")) { /*if (msg.equals("fullpath")) {
if (pathingBehavior.getGoal() == null) { if (pathingBehavior.getGoal() == null) {
logDirect("No goal."); logDirect("No goal.");
} else { } else {
@@ -225,7 +223,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
}); });
} }
return true; return true;
} }*/
if (msg.equals("proc")) { if (msg.equals("proc")) {
Optional<IBaritoneProcess> proc = baritone.getPathingControlManager().mostRecentInControl(); Optional<IBaritoneProcess> proc = baritone.getPathingControlManager().mostRecentInControl();
if (!proc.isPresent()) { if (!proc.isPresent()) {
@@ -283,7 +281,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
return true; return true;
} }
if (msg.equals("come")) { if (msg.equals("come")) {
customGoalProcess.setGoalAndPath(new GoalBlock(new BlockPos(mc.getRenderViewEntity()))); customGoalProcess.setGoalAndPath(new GoalBlock(new BlockPos(Helper.mc.getRenderViewEntity())));
logDirect("Coming"); logDirect("Coming");
return true; return true;
} }
@@ -353,21 +351,42 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
baritone.getBuilderProcess().clearArea(corner1, corner2); baritone.getBuilderProcess().clearArea(corner1, corner2);
return true; 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")) { if (msg.equals("reset")) {
for (Settings.Setting setting : Baritone.settings().allSettings) { for (Settings.Setting setting : BaritoneAPI.getSettings().allSettings) {
setting.reset(); setting.reset();
} }
SettingsUtil.save(Baritone.settings()); SettingsUtil.save(BaritoneAPI.getSettings());
logDirect("Baritone settings reset"); logDirect("Baritone settings reset");
return true; return true;
} }
if (msg.equals("tunnel")) {
customGoalProcess.setGoalAndPath(new GoalStrictDirection(ctx.playerFeet(), ctx.player().getHorizontalFacing()));
logDirect("tunneling");
return true;
}
if (msg.equals("render")) { if (msg.equals("render")) {
BetterBlockPos pf = ctx.playerFeet(); 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); Minecraft.getMinecraft().renderGlobal.markBlockRangeForRenderUpdate(pf.x - 500, pf.y - 500, pf.z - 500, pf.x + 500, pf.y + 500, pf.z + 500);
logDirect("okay"); logDirect("okay");
return true; 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(); Optional<List<ItemStack>> contents = baritone.getMemoryBehavior().echest();
if (contents.isPresent()) { if (contents.isPresent()) {
logDirect("echest contents:"); logDirect("echest contents:");
@@ -376,18 +395,8 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
logDirect("echest contents unknown"); logDirect("echest contents unknown");
} }
return true; return true;
} }*/
if (msg.equals("chests")) { 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()) { for (Map.Entry<BlockPos, IRememberedInventory> entry : baritone.getWorldProvider().getCurrentWorld().getContainerMemory().getRememberedInventories().entrySet()) {
logDirect(entry.getKey() + ""); logDirect(entry.getKey() + "");
log(entry.getValue().getContents()); log(entry.getValue().getContents());
@@ -421,6 +430,29 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
logDirect("Following " + toFollow.get()); logDirect("Following " + toFollow.get());
return true; 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")) { if (msg.equals("reloadall")) {
baritone.getWorldProvider().getCurrentWorld().getCachedWorld().reloadAllFromDisk(); baritone.getWorldProvider().getCurrentWorld().getCachedWorld().reloadAllFromDisk();
logDirect("ok"); logDirect("ok");
@@ -446,14 +478,27 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
logDirect("Exploring from " + centerX + "," + centerZ); logDirect("Exploring from " + centerX + "," + centerZ);
return true; 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")) { if (msg.startsWith("find")) {
String blockType = msg.substring(4).trim(); String blockType = msg.substring(4).trim();
ArrayList<BlockPos> locs = baritone.getWorldProvider().getCurrentWorld().getCachedWorld().getLocationsOf(blockType, 1, ctx.playerFeet().getX(), ctx.playerFeet().getZ(), 4); ArrayList<BlockPos> locs = baritone.getWorldProvider().getCurrentWorld().getCachedWorld().getLocationsOf(blockType, 1, ctx.playerFeet().getX(), ctx.playerFeet().getZ(), 4);
logDirect("Have " + locs.size() + " locations"); logDirect("Have " + locs.size() + " locations");
for (BlockPos pos : locs) { for (BlockPos pos : locs) {
Block actually = BlockStateInterface.get(ctx, pos).getBlock(); Block actually = ctx.world().getBlockState(pos).getBlock();
if (!ChunkPacker.blockToString(actually).equalsIgnoreCase(blockType)) { if (!BlockUtils.blockToString(actually).equalsIgnoreCase(blockType)) {
System.out.println("Was looking for " + blockType + " but actually found " + actually + " " + ChunkPacker.blockToString(actually)); logDebug("Was looking for " + blockType + " but actually found " + actually + " " + BlockUtils.blockToString(actually));
} }
} }
return true; return true;
@@ -462,14 +507,13 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
String[] blockTypes = msg.substring(4).trim().split(" "); String[] blockTypes = msg.substring(4).trim().split(" ");
try { try {
int quantity = Integer.parseInt(blockTypes[1]); int quantity = Integer.parseInt(blockTypes[1]);
Block block = ChunkPacker.stringToBlock(blockTypes[0]); Block block = BlockUtils.stringToBlockRequired(blockTypes[0]);
Objects.requireNonNull(block);
baritone.getMineProcess().mine(quantity, block); baritone.getMineProcess().mine(quantity, block);
logDirect("Will mine " + quantity + " " + blockTypes[0]); logDirect("Will mine " + quantity + " " + blockTypes[0]);
return true; return true;
} catch (NumberFormatException | ArrayIndexOutOfBoundsException | NullPointerException ex) {} } catch (NumberFormatException | ArrayIndexOutOfBoundsException | NullPointerException ex) {}
for (String s : blockTypes) { for (String s : blockTypes) {
if (ChunkPacker.stringToBlock(s) == null) { if (BlockUtils.stringToBlockNullable(s) == null) {
logDirect(s + " isn't a valid block name"); logDirect(s + " isn't a valid block name");
return true; return true;
} }
@@ -480,12 +524,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
return true; return true;
} }
if (msg.equals("click")) { if (msg.equals("click")) {
new Thread(() -> { baritone.openClick();
try {
Thread.sleep(100);
mc.addScheduledTask(() -> mc.displayGuiScreen(new GuiClick()));
} catch (Exception ignored) {}
}).start();
logDirect("aight dude"); logDirect("aight dude");
return true; return true;
} }
@@ -505,9 +544,9 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
// for example, "show deaths" // for example, "show deaths"
waypointType = waypointType.substring(0, waypointType.length() - 1); waypointType = waypointType.substring(0, waypointType.length() - 1);
} }
Waypoint.Tag tag = Waypoint.Tag.fromString(waypointType); IWaypoint.Tag tag = IWaypoint.Tag.fromString(waypointType);
if (tag == null) { 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; return true;
} }
Set<IWaypoint> waypoints = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getByTag(tag); Set<IWaypoint> waypoints = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getByTag(tag);
@@ -538,21 +577,21 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
} }
name = parts[0]; 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."); logDirect("Saved user defined position " + pos + " under name '" + name + "'. Say 'goto " + name + "' to set goal, say 'list user' to list custom waypoints.");
return true; return true;
} }
if (msg.startsWith("goto")) { if (msg.startsWith("goto")) {
String waypointType = msg.substring(4).trim(); 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" // for example, "show deaths"
waypointType = waypointType.substring(0, waypointType.length() - 1); waypointType = waypointType.substring(0, waypointType.length() - 1);
} }
Waypoint.Tag tag = Waypoint.Tag.fromString(waypointType); IWaypoint.Tag tag = IWaypoint.Tag.fromString(waypointType);
IWaypoint waypoint; IWaypoint waypoint;
if (tag == null) { if (tag == null) {
String mining = waypointType; String mining = waypointType;
Block block = ChunkPacker.stringToBlock(mining); Block block = BlockUtils.stringToBlockNullable(mining);
//logDirect("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase()); //logDirect("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
if (block == null) { if (block == null) {
waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getAllWaypoints().stream().filter(w -> w.getName().equalsIgnoreCase(mining)).max(Comparator.comparingLong(IWaypoint::getCreationTimestamp)).orElse(null); waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getAllWaypoints().stream().filter(w -> w.getName().equalsIgnoreCase(mining)).max(Comparator.comparingLong(IWaypoint::getCreationTimestamp)).orElse(null);
@@ -575,12 +614,12 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
return true; 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); customGoalProcess.setGoalAndPath(goal);
return true; return true;
} }
if (msg.equals("spawn") || msg.equals("bed")) { 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) { if (waypoint == null) {
BlockPos spawnPoint = ctx.player().getBedLocation(); BlockPos spawnPoint = ctx.player().getBedLocation();
// for some reason the default spawnpoint is underground sometimes // for some reason the default spawnpoint is underground sometimes
@@ -595,12 +634,12 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
return true; return true;
} }
if (msg.equals("sethome")) { 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."); logDirect("Saved. Say home to set goal.");
return true; return true;
} }
if (msg.equals("home")) { 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) { if (waypoint == null) {
logDirect("home not saved"); logDirect("home not saved");
} else { } else {
@@ -610,7 +649,8 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
} }
return true; 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)); 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)) { while (moves.contains(null)) {
moves.remove(null); moves.remove(null);
@@ -626,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); logDirect(parts[parts.length - 1] + " " + move.getDest().getX() + "," + move.getDest().getY() + "," + move.getDest().getZ() + " " + strCost);
} }
return true; return true;
} }*/
if (msg.equals("damn")) { if (msg.equals("damn")) {
logDirect("daniel"); logDirect("daniel");
} }
@@ -15,9 +15,9 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>. * 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.client.Minecraft;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentString;
@@ -50,7 +50,7 @@ public interface Helper {
* @param message The message to display in chat * @param message The message to display in chat
*/ */
default void logDebug(String message) { default void logDebug(String message) {
if (!Baritone.settings().chatDebug.value) { if (!BaritoneAPI.getSettings().chatDebug.value) {
//System.out.println("Suppressed debug message:"); //System.out.println("Suppressed debug message:");
//System.out.println(message); //System.out.println(message);
return; return;
@@ -67,6 +67,6 @@ public interface Helper {
ITextComponent component = MESSAGE_PREFIX.createCopy(); ITextComponent component = MESSAGE_PREFIX.createCopy();
component.getStyle().setColor(TextFormatting.GRAY); component.getStyle().setColor(TextFormatting.GRAY);
component.appendSibling(new TextComponentString(" " + message)); 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 * @return The position of the highlighted block
*/ */
default Optional<BlockPos> getSelectedBlock() { default Optional<BlockPos> getSelectedBlock() {
if (objectMouseOver() != null && objectMouseOver().typeOfHit == RayTraceResult.Type.BLOCK) { RayTraceResult result = objectMouseOver();
return Optional.of(objectMouseOver().getBlockPos()); if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
return Optional.of(result.getBlockPos());
} }
return Optional.empty(); 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. * Returns the entity that the crosshair is currently placed over. Updated once per tick.
* *
* @return The entity * @return The entity
*/ */
default Optional<Entity> getSelectedEntity() { default Optional<Entity> getSelectedEntity() {
if (objectMouseOver() != null && objectMouseOver().typeOfHit == RayTraceResult.Type.ENTITY) { RayTraceResult result = objectMouseOver();
return Optional.of(objectMouseOver().entityHit); if (result != null && result.typeOfHit == RayTraceResult.Type.ENTITY) {
return Optional.of(result.entityHit);
} }
return Optional.empty(); return Optional.empty();
} }
@@ -50,4 +50,6 @@ public interface IPlayerController {
} }
EnumActionResult processRightClickBlock(EntityPlayerSP player, World world, BlockPos pos, EnumFacing direction, Vec3d vec, EnumHand hand); EnumActionResult processRightClickBlock(EntityPlayerSP player, World world, BlockPos pos, EnumFacing direction, Vec3d vec, EnumHand hand);
EnumActionResult processRightClick(EntityPlayerSP player, World world, EnumHand hand);
} }
@@ -18,6 +18,7 @@
package baritone.api.utils; package baritone.api.utils;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.util.EnumFacing;
/** /**
* Basic representation of a schematic. Provides the dimensions and * 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(); 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). * Returns the desired block state at a given (X, Y, Z) position relative to the origin (0, 0, 0).
* *
@@ -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;
}
}
+105 -24
View File
@@ -18,32 +18,33 @@
package baritone.api.utils; package baritone.api.utils;
import baritone.api.Settings; import baritone.api.Settings;
import net.minecraft.block.Block;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.EnumFacing;
import java.awt.*; import java.awt.*;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.*; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import static net.minecraft.client.Minecraft.getMinecraft; import static net.minecraft.client.Minecraft.getMinecraft;
public class SettingsUtil { public class SettingsUtil {
private static final Path SETTINGS_PATH = getMinecraft().gameDir.toPath().resolve("baritone").resolve("settings.txt"); 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 Pattern SETTING_PATTERN = Pattern.compile("^(?<setting>[^ ]+) +(?<value>.+)"); // key and value split by the first space
private static final Map<Class<?>, SettingsIO> map;
private static boolean isComment(String line) { private static boolean isComment(String line) {
return line.startsWith("#") || line.startsWith("//"); return line.startsWith("#") || line.startsWith("//");
@@ -118,11 +119,11 @@ public class SettingsUtil {
if (setting.getName().equals("logger")) { if (setting.getName().equals("logger")) {
return "logger"; return "logger";
} }
SettingsIO io = map.get(setting.getValueClass()); Parser io = Parser.getParser(setting.getType());
if (io == null) { if (io == null) {
throw new IllegalStateException("Missing " + setting.getValueClass() + " " + setting.getName()); 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 { 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"); throw new IllegalStateException("No setting by that name");
} }
Class intendedType = setting.getValueClass(); Class intendedType = setting.getValueClass();
SettingsIO ioMethod = map.get(intendedType); ISettingParser ioMethod = Parser.getParser(setting.getType());
Object parsed = ioMethod.parser.apply(settingValue); Object parsed = ioMethod.parse(new ParserContext(setting), settingValue);
if (!intendedType.isInstance(parsed)) { if (!intendedType.isInstance(parsed)) {
throw new IllegalStateException(ioMethod + " parser returned incorrect type, expected " + intendedType + " got " + parsed + " which is " + parsed.getClass()); throw new IllegalStateException(ioMethod + " parser returned incorrect type, expected " + intendedType + " got " + parsed + " which is " + parsed.getClass());
} }
setting.value = parsed; 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), DOUBLE(Double.class, Double::parseDouble),
BOOLEAN(Boolean.class, Boolean::parseBoolean), BOOLEAN(Boolean.class, Boolean::parseBoolean),
INTEGER(Integer.class, Integer::parseInt), INTEGER(Integer.class, Integer::parseInt),
FLOAT(Float.class, Float::parseFloat), FLOAT(Float.class, Float::parseFloat),
LONG(Long.class, Long::parseLong), 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(","))), return Arrays.stream(raw.split(","))
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()); .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; return ((List<?>) value).stream()
Function<String, Object> parser; .map(o -> parser.toString(context, o))
Function<Object, String> toString; .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); 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.klass = klass;
this.parser = parser::apply; this.parser = parser::apply;
this.toString = x -> toString.apply((T) x); this.toString = x -> toString.apply((T) x);
} }
}
static { @Override
HashMap<Class<?>, SettingsIO> tempMap = new HashMap<>(); public Object parse(ParserContext context, String raw) {
for (SettingsIO type : SettingsIO.values()) { return this.parser.apply(raw);
tempMap.put(type.klass, type); }
@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);
} }
} }
@@ -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;
}
}
+20 -9
View File
@@ -21,6 +21,8 @@ import baritone.api.BaritoneAPI;
import baritone.api.IBaritone; import baritone.api.IBaritone;
import baritone.api.Settings; import baritone.api.Settings;
import baritone.api.event.listener.IEventBus; import baritone.api.event.listener.IEventBus;
import baritone.api.utils.ExampleBaritoneControl;
import baritone.api.utils.Helper;
import baritone.api.utils.IPlayerContext; import baritone.api.utils.IPlayerContext;
import baritone.behavior.*; import baritone.behavior.*;
import baritone.cache.WorldProvider; import baritone.cache.WorldProvider;
@@ -33,8 +35,6 @@ import net.minecraft.client.Minecraft;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.SynchronousQueue; import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
@@ -67,7 +67,6 @@ public class Baritone implements IBaritone {
private GameEventHandler gameEventHandler; private GameEventHandler gameEventHandler;
private List<Behavior> behaviors;
private PathingBehavior pathingBehavior; private PathingBehavior pathingBehavior;
private LookBehavior lookBehavior; private LookBehavior lookBehavior;
private MemoryBehavior memoryBehavior; private MemoryBehavior memoryBehavior;
@@ -80,6 +79,8 @@ public class Baritone implements IBaritone {
private CustomGoalProcess customGoalProcess; private CustomGoalProcess customGoalProcess;
private BuilderProcess builderProcess; private BuilderProcess builderProcess;
private ExploreProcess exploreProcess; private ExploreProcess exploreProcess;
private BackfillProcess backfillProcess;
private FarmProcess farmProcess;
private PathingControlManager pathingControlManager; 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! // Define this before behaviors try and get it, or else it will be null and the builds will fail!
this.playerContext = PrimaryPlayerContext.INSTANCE; this.playerContext = PrimaryPlayerContext.INSTANCE;
this.behaviors = new ArrayList<>();
{ {
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist // the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
pathingBehavior = new PathingBehavior(this); pathingBehavior = new PathingBehavior(this);
@@ -120,6 +120,8 @@ public class Baritone implements IBaritone {
getToBlockProcess = new GetToBlockProcess(this); getToBlockProcess = new GetToBlockProcess(this);
builderProcess = new BuilderProcess(this); builderProcess = new BuilderProcess(this);
exploreProcess = new ExploreProcess(this); exploreProcess = new ExploreProcess(this);
backfillProcess = new BackfillProcess(this);
farmProcess = new FarmProcess(this);
} }
this.worldProvider = new WorldProvider(); this.worldProvider = new WorldProvider();
@@ -136,12 +138,7 @@ public class Baritone implements IBaritone {
return this.pathingControlManager; return this.pathingControlManager;
} }
public List<Behavior> getBehaviors() {
return this.behaviors;
}
public void registerBehavior(Behavior behavior) { public void registerBehavior(Behavior behavior) {
this.behaviors.add(behavior);
this.gameEventHandler.registerEventListener(behavior); this.gameEventHandler.registerEventListener(behavior);
} }
@@ -197,6 +194,10 @@ public class Baritone implements IBaritone {
return this.mineProcess; return this.mineProcess;
} }
public FarmProcess getFarmProcess() {
return this.farmProcess;
}
@Override @Override
public PathingBehavior getPathingBehavior() { public PathingBehavior getPathingBehavior() {
return this.pathingBehavior; return this.pathingBehavior;
@@ -212,6 +213,16 @@ public class Baritone implements IBaritone {
return this.gameEventHandler; 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() { public static Settings settings() {
return BaritoneAPI.getSettings(); return BaritoneAPI.getSettings();
} }
@@ -123,27 +123,27 @@ public class InventoryBehavior extends Behavior {
public boolean hasGenericThrowaway() { public boolean hasGenericThrowaway() {
for (Item item : Baritone.settings().acceptableThrowawayItems.value) { for (Item item : Baritone.settings().acceptableThrowawayItems.value) {
if (throwaway(false, item::equals)) { if (throwaway(false, stack -> item.equals(stack.getItem()))) {
return true; return true;
} }
} }
return false; 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); 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 return true; // gotem
} }
for (Item item : Baritone.settings().acceptableThrowawayItems.value) { for (Item item : Baritone.settings().acceptableThrowawayItems.value) {
if (throwaway(true, item::equals)) { if (throwaway(select, stack -> item.equals(stack.getItem()))) {
return true; return true;
} }
} }
return false; return false;
} }
private boolean throwaway(boolean select, Predicate<? super Item> desired) { public boolean throwaway(boolean select, Predicate<? super ItemStack> desired) {
EntityPlayerSP p = ctx.player(); EntityPlayerSP p = ctx.player();
NonNullList<ItemStack> inv = p.inventory.mainInventory; NonNullList<ItemStack> inv = p.inventory.mainInventory;
for (byte i = 0; i < 9; i++) { for (byte i = 0; i < 9; i++) {
@@ -153,14 +153,14 @@ public class InventoryBehavior extends Behavior {
// and then it's called during execution // and then it's called during execution
// since this function is never called during cost calculation, we don't need to migrate // since this function is never called during cost calculation, we don't need to migrate
// acceptableThrowawayItems to the CalculationContext // acceptableThrowawayItems to the CalculationContext
if (desired.test(item.getItem())) { if (desired.test(item)) {
if (select) { if (select) {
p.inventory.currentItem = i; p.inventory.currentItem = i;
} }
return true; 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 // 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 // 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 // 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 oldPitch = ctx.player().rotationPitch;
float desiredPitch = this.target.getPitch(); float desiredPitch = this.target.getPitch();
ctx.player().rotationPitch = desiredPitch; ctx.player().rotationPitch = desiredPitch;
if (desiredPitch == oldPitch) { if (desiredPitch == oldPitch && !Baritone.settings().freeLook.value) {
//nudgeToLevel(); nudgeToLevel();
} }
this.target = null; this.target = null;
} }
@@ -18,13 +18,13 @@
package baritone.behavior; package baritone.behavior;
import baritone.Baritone; import baritone.Baritone;
import baritone.api.cache.Waypoint;
import baritone.api.event.events.BlockInteractEvent; import baritone.api.event.events.BlockInteractEvent;
import baritone.api.event.events.PacketEvent; import baritone.api.event.events.PacketEvent;
import baritone.api.event.events.PlayerUpdateEvent; import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.TickEvent; import baritone.api.event.events.TickEvent;
import baritone.api.event.events.type.EventState; import baritone.api.event.events.type.EventState;
import baritone.cache.ContainerMemory; import baritone.cache.ContainerMemory;
import baritone.cache.Waypoint;
import baritone.utils.BlockStateInterface; import baritone.utils.BlockStateInterface;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockBed; import net.minecraft.block.BlockBed;
@@ -25,6 +25,7 @@ import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalXZ; import baritone.api.pathing.goals.GoalXZ;
import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommand;
import baritone.api.utils.BetterBlockPos; import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Helper;
import baritone.api.utils.PathCalculationResult; import baritone.api.utils.PathCalculationResult;
import baritone.api.utils.interfaces.IGoalRenderPos; import baritone.api.utils.interfaces.IGoalRenderPos;
import baritone.pathing.calc.AStarPathFinder; import baritone.pathing.calc.AStarPathFinder;
@@ -32,7 +33,6 @@ import baritone.pathing.calc.AbstractNodeCostSearch;
import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.MovementHelper; import baritone.pathing.movement.MovementHelper;
import baritone.pathing.path.PathExecutor; import baritone.pathing.path.PathExecutor;
import baritone.utils.Helper;
import baritone.utils.PathRenderer; import baritone.utils.PathRenderer;
import baritone.utils.PathingCommandContext; import baritone.utils.PathingCommandContext;
import baritone.utils.pathing.Favoring; import baritone.utils.pathing.Favoring;
@@ -325,6 +325,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
public void softCancelIfSafe() { public void softCancelIfSafe() {
synchronized (pathPlanLock) { synchronized (pathPlanLock) {
getInProgress().ifPresent(AbstractNodeCostSearch::cancel); // only cancel ours
if (!isSafeToCancel()) { if (!isSafeToCancel()) {
return; return;
} }
@@ -332,7 +333,6 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
next = null; next = null;
} }
cancelRequested = true; cancelRequested = true;
getInProgress().ifPresent(AbstractNodeCostSearch::cancel); // only cancel ours
// do everything BUT clear keys // do everything BUT clear keys
} }
@@ -340,17 +340,18 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
public void secretInternalSegmentCancel() { public void secretInternalSegmentCancel() {
queuePathEvent(PathEvent.CANCELED); queuePathEvent(PathEvent.CANCELED);
synchronized (pathPlanLock) { synchronized (pathPlanLock) {
getInProgress().ifPresent(AbstractNodeCostSearch::cancel);
if (current != null) { if (current != null) {
current = null; current = null;
next = null; next = null;
baritone.getInputOverrideHandler().clearAllKeys(); baritone.getInputOverrideHandler().clearAllKeys();
getInProgress().ifPresent(AbstractNodeCostSearch::cancel);
baritone.getInputOverrideHandler().getBlockBreakHelper().stopBreakingBlock(); baritone.getInputOverrideHandler().getBlockBreakHelper().stopBreakingBlock();
} }
} }
} }
public void forceCancel() { // NOT exposed on public api @Override
public void forceCancel() { // exposed on public api because :sob:
cancelEverything(); cancelEverything();
secretInternalSegmentCancel(); secretInternalSegmentCancel();
synchronized (pathCalcLock) { 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) { synchronized (pathPlanLock) {
current = new PathExecutor(this, path); current = new PathExecutor(this, path);
} }
} }*/
public CalculationContext secretInternalGetCalculationContext() { public CalculationContext secretInternalGetCalculationContext() {
return context; return context;
+2 -1
View File
@@ -17,6 +17,7 @@
package baritone.cache; package baritone.cache;
import baritone.api.utils.BlockUtils;
import baritone.utils.pathing.PathingBlockType; import baritone.utils.pathing.PathingBlockType;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minecraft.block.Block; import net.minecraft.block.Block;
@@ -177,7 +178,7 @@ public final class CachedChunk {
if (special != null) { if (special != null) {
String str = special.get(index); String str = special.get(index);
if (str != null) { if (str != null) {
return ChunkPacker.stringToBlock(str).getDefaultState(); return BlockUtils.stringToBlockRequired(str).getDefaultState();
} }
} }
+4 -2
View File
@@ -19,6 +19,7 @@ package baritone.cache;
import baritone.Baritone; import baritone.Baritone;
import baritone.api.cache.ICachedRegion; import baritone.api.cache.ICachedRegion;
import baritone.api.utils.BlockUtils;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@@ -149,7 +150,7 @@ public final class CachedRegion implements ICachedRegion {
for (int z = 0; z < 32; z++) { for (int z = 0; z < 32; z++) {
if (chunks[x][z] != null) { if (chunks[x][z] != null) {
for (int i = 0; i < 256; i++) { 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++) { for (int z = 0; z < 32; z++) {
if (present[x][z]) { if (present[x][z]) {
for (int i = 0; i < 256; i++) { for (int i = 0; i < 256; i++) {
overview[x][z][i] = ChunkPacker.stringToBlock(in.readUTF()).getDefaultState(); overview[x][z][i] = BlockUtils.stringToBlockRequired(in.readUTF()).getDefaultState();
} }
} }
} }
@@ -255,6 +256,7 @@ public final class CachedRegion implements ICachedRegion {
int numSpecialBlockTypes = in.readShort() & 0xffff; int numSpecialBlockTypes = in.readShort() & 0xffff;
for (int i = 0; i < numSpecialBlockTypes; i++) { for (int i = 0; i < numSpecialBlockTypes; i++) {
String blockName = in.readUTF(); String blockName = in.readUTF();
BlockUtils.stringToBlockRequired(blockName);
List<BlockPos> locs = new ArrayList<>(); List<BlockPos> locs = new ArrayList<>();
location[x][z].put(blockName, locs); location[x][z].put(blockName, locs);
int numLocations = in.readShort() & 0xffff; int numLocations = in.readShort() & 0xffff;
+4 -6
View File
@@ -22,7 +22,7 @@ import baritone.api.BaritoneAPI;
import baritone.api.IBaritone; import baritone.api.IBaritone;
import baritone.api.cache.ICachedWorld; import baritone.api.cache.ICachedWorld;
import baritone.api.cache.IWorldData; 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.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@@ -70,8 +70,6 @@ public final class CachedWorld implements ICachedWorld, Helper {
this.directory = directory.toString(); this.directory = directory.toString();
this.dimension = dimension; this.dimension = dimension;
System.out.println("Cached world directory: " + directory); System.out.println("Cached world directory: " + directory);
// Insert an invalid region element
cachedRegions.put(0, null);
Baritone.getExecutor().execute(new PackerThread()); Baritone.getExecutor().execute(new PackerThread());
Baritone.getExecutor().execute(() -> { Baritone.getExecutor().execute(() -> {
try { try {
@@ -182,8 +180,8 @@ public final class CachedWorld implements ICachedWorld, Helper {
if (region == null) { if (region == null) {
continue; continue;
} }
int distX = (region.getX() << 9 + 256) - pruneCenter.getX(); int distX = ((region.getX() << 9) + 256) - pruneCenter.getX();
int distZ = (region.getZ() << 9 + 256) - pruneCenter.getZ(); int distZ = ((region.getZ() << 9) + 256) - pruneCenter.getZ();
double dist = Math.sqrt(distX * distX + distZ * distZ); double dist = Math.sqrt(distX * distX + distZ * distZ);
if (dist > 1024) { if (dist > 1024) {
logDebug("Deleting cached region " + region.getX() + "," + region.getZ() + " from ram"); logDebug("Deleting cached region " + region.getX() + "," + region.getZ() + " from ram");
@@ -218,7 +216,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
if (mostRecentlyModified == null) { if (mostRecentlyModified == null) {
return new BlockPos(0, 0, 0); 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() { private synchronized List<CachedRegion> allRegions() {
+11 -22
View File
@@ -17,12 +17,12 @@
package baritone.cache; package baritone.cache;
import baritone.api.utils.BlockUtils;
import baritone.pathing.movement.MovementHelper; import baritone.pathing.movement.MovementHelper;
import baritone.utils.pathing.PathingBlockType; import baritone.utils.pathing.PathingBlockType;
import net.minecraft.block.*; import net.minecraft.block.*;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.BlockStateContainer; import net.minecraft.world.chunk.BlockStateContainer;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.Chunk;
@@ -36,8 +36,6 @@ import java.util.*;
*/ */
public final class ChunkPacker { public final class ChunkPacker {
private static final Map<String, Block> resourceCache = new HashMap<>();
private ChunkPacker() {} private ChunkPacker() {}
public static CachedChunk pack(Chunk chunk) { public static CachedChunk pack(Chunk chunk) {
@@ -75,7 +73,7 @@ public final class ChunkPacker {
bitSet.set(index + 1, bits[1]); bitSet.set(index + 1, bits[1]);
Block block = state.getBlock(); Block block = state.getBlock();
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(block)) { 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)); specialBlocks.computeIfAbsent(name, b -> new ArrayList<>()).add(new BlockPos(x, y, z));
} }
} }
@@ -90,8 +88,7 @@ public final class ChunkPacker {
IBlockState[] blocks = new IBlockState[256]; IBlockState[] blocks = new IBlockState[256];
for (int z = 0; z < 16; z++) { for (int z = 0; z < 16; z++) {
https: https://www.ibm.com/developerworks/library/j-perry-writing-good-java-code/index.html
//www.ibm.com/developerworks/library/j-perry-writing-good-java-code/index.html
for (int x = 0; x < 16; x++) { for (int x = 0; x < 16; x++) {
for (int y = 255; y >= 0; y--) { for (int y = 255; y >= 0; y--) {
int index = CachedChunk.getPositionIndex(x, y, z); int index = CachedChunk.getPositionIndex(x, y, z);
@@ -106,19 +103,6 @@ public final class ChunkPacker {
return new CachedChunk(chunk.x, chunk.z, bitSet, blocks, specialBlocks, System.currentTimeMillis()); 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 stringToBlock(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) { private static PathingBlockType getPathingBlockType(IBlockState state, Chunk chunk, int x, int y, int z) {
Block block = state.getBlock(); Block block = state.getBlock();
@@ -128,15 +112,20 @@ public final class ChunkPacker {
if (MovementHelper.possiblyFlowing(state)) { if (MovementHelper.possiblyFlowing(state)) {
return PathingBlockType.AVOID; 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 (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) { 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.WATER;
} }
return PathingBlockType.AVOID; 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; return PathingBlockType.WATER;
} }
+1
View File
@@ -19,6 +19,7 @@ package baritone.cache;
import baritone.api.cache.IWaypoint; import baritone.api.cache.IWaypoint;
import baritone.api.cache.IWaypointCollection; import baritone.api.cache.IWaypointCollection;
import baritone.api.cache.Waypoint;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import java.io.*; import java.io.*;
+1 -1
View File
@@ -19,7 +19,7 @@ package baritone.cache;
import baritone.Baritone; import baritone.Baritone;
import baritone.api.cache.IWorldProvider; import baritone.api.cache.IWorldProvider;
import baritone.utils.Helper; import baritone.api.utils.Helper;
import baritone.utils.accessor.IAnvilChunkLoader; import baritone.utils.accessor.IAnvilChunkLoader;
import baritone.utils.accessor.IChunkProviderServer; import baritone.utils.accessor.IChunkProviderServer;
import net.minecraft.server.integrated.IntegratedServer; import net.minecraft.server.integrated.IntegratedServer;
+27 -11
View File
@@ -28,15 +28,15 @@ import net.minecraft.world.chunk.BlockStateContainer;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage; import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import java.util.ArrayList; import java.util.*;
import java.util.Collection; import java.util.stream.IntStream;
import java.util.Collections;
import java.util.List;
public enum WorldScanner implements IWorldScanner { public enum WorldScanner implements IWorldScanner {
INSTANCE; INSTANCE;
private static final int[] DEFAULT_COORDINATE_ITERATION_ORDER = IntStream.range(0, 16).toArray();
@Override @Override
public List<BlockPos> scanChunkRadius(IPlayerContext ctx, List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius) { public List<BlockPos> scanChunkRadius(IPlayerContext ctx, List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius) {
if (blocks.contains(null)) { if (blocks.contains(null)) {
@@ -53,6 +53,9 @@ public enum WorldScanner implements IWorldScanner {
int playerChunkZ = ctx.playerFeet().getZ() >> 4; int playerChunkZ = ctx.playerFeet().getZ() >> 4;
int playerY = ctx.playerFeet().getY(); 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; int searchRadiusSq = 0;
boolean foundWithinY = false; boolean foundWithinY = false;
while (true) { while (true) {
@@ -72,7 +75,9 @@ public enum WorldScanner implements IWorldScanner {
continue; continue;
} }
allUnloaded = false; 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) if ((allUnloaded && foundChunks)
@@ -100,13 +105,15 @@ public enum WorldScanner implements IWorldScanner {
} }
ArrayList<BlockPos> res = new ArrayList<>(); 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; 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(); 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]; ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
if (extendedblockstorage == null) { if (extendedblockstorage == null) {
continue; continue;
@@ -121,14 +128,23 @@ public enum WorldScanner implements IWorldScanner {
IBlockState state = bsc.get(x, y, z); IBlockState state = bsc.get(x, y, z);
if (search.contains(state.getBlock())) { if (search.contains(state.getBlock())) {
int yy = yReal | y; int yy = yReal | y;
result.add(new BlockPos(chunkX | x, yy, chunkZ | z)); if (result.size() >= max) {
if (result.size() >= max && Math.abs(yy - playerY) < yLevelThreshold) { if (Math.abs(yy - playerY) < yLevelThreshold) {
return; 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.events.type.EventState;
import baritone.api.event.listener.IEventBus; import baritone.api.event.listener.IEventBus;
import baritone.api.event.listener.IGameEventListener; import baritone.api.event.listener.IGameEventListener;
import baritone.api.utils.Helper;
import baritone.cache.WorldProvider; import baritone.cache.WorldProvider;
import baritone.utils.BlockStateInterface; import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk; 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.calc.IPathFinder;
import baritone.api.pathing.goals.Goal; import baritone.api.pathing.goals.Goal;
import baritone.api.utils.BetterBlockPos; import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Helper;
import baritone.api.utils.PathCalculationResult; import baritone.api.utils.PathCalculationResult;
import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.CalculationContext;
import baritone.utils.Helper;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import java.util.Optional; import java.util.Optional;
@@ -186,7 +186,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder, Helper {
} }
protected Optional<IPath> bestSoFar(boolean logInfo, int numNodes) { protected Optional<IPath> bestSoFar(boolean logInfo, int numNodes) {
if (startNode == null || bestSoFar == null) { if (startNode == null) {
return Optional.empty(); return Optional.empty();
} }
double bestDist = 0; double bestDist = 0;
@@ -21,11 +21,11 @@ import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.Goal; import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.movement.IMovement; import baritone.api.pathing.movement.IMovement;
import baritone.api.utils.BetterBlockPos; import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Helper;
import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement; import baritone.pathing.movement.Movement;
import baritone.pathing.movement.Moves; import baritone.pathing.movement.Moves;
import baritone.pathing.path.CutoffPath; import baritone.pathing.path.CutoffPath;
import baritone.utils.Helper;
import baritone.utils.pathing.PathBase; import baritone.utils.pathing.PathBase;
import java.util.ArrayList; import java.util.ArrayList;
@@ -60,6 +60,7 @@ public class CalculationContext {
public final boolean allowJumpAt256; public final boolean allowJumpAt256;
public final boolean assumeWalkOnWater; public final boolean assumeWalkOnWater;
public final boolean allowDiagonalDescend; public final boolean allowDiagonalDescend;
public final boolean allowDownward;
public final int maxFallHeightNoWater; public final int maxFallHeightNoWater;
public final int maxFallHeightBucket; public final int maxFallHeightBucket;
public final double waterWalkSpeed; public final double waterWalkSpeed;
@@ -91,6 +92,7 @@ public class CalculationContext {
this.allowJumpAt256 = Baritone.settings().allowJumpAt256.value; this.allowJumpAt256 = Baritone.settings().allowJumpAt256.value;
this.assumeWalkOnWater = Baritone.settings().assumeWalkOnWater.value; this.assumeWalkOnWater = Baritone.settings().assumeWalkOnWater.value;
this.allowDiagonalDescend = Baritone.settings().allowDiagonalDescend.value; this.allowDiagonalDescend = Baritone.settings().allowDiagonalDescend.value;
this.allowDownward = Baritone.settings().allowDownward.value;
this.maxFallHeightNoWater = Baritone.settings().maxFallHeightNoWater.value; this.maxFallHeightNoWater = Baritone.settings().maxFallHeightNoWater.value;
this.maxFallHeightBucket = Baritone.settings().maxFallHeightBucket.value; this.maxFallHeightBucket = Baritone.settings().maxFallHeightBucket.value;
int depth = EnchantmentHelper.getDepthStriderModifier(player); int depth = EnchantmentHelper.getDepthStriderModifier(player);
@@ -270,4 +270,8 @@ public abstract class Movement implements IMovement, MovementHelper {
} }
return toWalkIntoCached; return toWalkIntoCached;
} }
public BlockPos[] toBreakAll() {
return positionsToBreak;
}
} }
@@ -25,7 +25,6 @@ import baritone.api.utils.*;
import baritone.api.utils.input.Input; import baritone.api.utils.input.Input;
import baritone.pathing.movement.MovementState.MovementTarget; import baritone.pathing.movement.MovementState.MovementTarget;
import baritone.utils.BlockStateInterface; import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import baritone.utils.ToolSet; import baritone.utils.ToolSet;
import net.minecraft.block.*; import net.minecraft.block.*;
import net.minecraft.block.properties.PropertyBool; 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 - 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; || bsi.get0(x, y, z - 1).getBlock() instanceof BlockLiquid
|| Baritone.settings().blocksToAvoidBreaking.value.contains(b);
} }
static boolean canWalkThrough(IPlayerContext ctx, BetterBlockPos pos) { static boolean canWalkThrough(IPlayerContext ctx, BetterBlockPos pos) {
@@ -72,7 +72,10 @@ public interface MovementHelper extends ActionCosts, Helper {
if (block == Blocks.AIR) { // early return for most common case if (block == Blocks.AIR) { // early return for most common case
return true; return true;
} }
if (block == Blocks.FIRE || block == Blocks.TRIPWIRE || block == Blocks.WEB || block == Blocks.END_PORTAL || block == Blocks.COCOA || block instanceof BlockSkull) { 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; return false;
} }
if (block instanceof BlockDoor || block instanceof BlockFenceGate) { if (block instanceof BlockDoor || block instanceof BlockFenceGate) {
@@ -84,9 +87,7 @@ public interface MovementHelper extends ActionCosts, Helper {
if (block == Blocks.CARPET) { if (block == Blocks.CARPET) {
return canWalkOn(bsi, x, y - 1, z); return canWalkOn(bsi, x, y - 1, z);
} }
boolean snow = block instanceof BlockSnow; if (block instanceof BlockSnow) {
boolean trapdoor = block instanceof BlockTrapDoor;
if (snow || trapdoor) {
// we've already checked doors and fence gates // we've already checked doors and fence gates
// so the only remaining dynamic isPassables are snow and trapdoor // so the only remaining dynamic isPassables are snow and trapdoor
// if they're cached as a top block, we don't know their metadata // if they're cached as a top block, we don't know their metadata
@@ -94,19 +95,13 @@ public interface MovementHelper extends ActionCosts, Helper {
if (!bsi.worldContainsLoadedChunk(x, z)) { if (!bsi.worldContainsLoadedChunk(x, z)) {
return true; return true;
} }
if (snow) { // the check in BlockSnow.isPassable is layers < 5
// the check in BlockSnow.isPassable is layers < 5 // while actually, we want < 3 because 3 or greater makes it impassable in a 2 high ceiling
// while actually, we want < 3 because 3 or greater makes it impassable in a 2 high ceiling if (state.getValue(BlockSnow.LAYERS) >= 3) {
if (state.getValue(BlockSnow.LAYERS) >= 3) { return false;
return false;
}
// ok, it's low enough we could walk through it, but is it supported?
return canWalkOn(bsi, x, y - 1, z);
} }
if (trapdoor) { // ok, it's low enough we could walk through it, but is it supported?
return !state.getValue(BlockTrapDoor.OPEN); // see BlockTrapDoor.isPassable return canWalkOn(bsi, x, y - 1, z);
}
throw new IllegalStateException();
} }
if (isFlowing(x, y, z, state, bsi)) { if (isFlowing(x, y, z, state, bsi)) {
return false; // Don't walk through flowing liquids return false; // Don't walk through flowing liquids
@@ -298,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 // if assumeWalkOnWater is off, we can only walk on water if there is water above it
return isWater(up) ^ Baritone.settings().assumeWalkOnWater.value; 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) { if (block == Blocks.GLASS || block == Blocks.STAINED_GLASS) {
return true; return true;
} }
@@ -317,6 +315,10 @@ public interface MovementHelper extends ActionCosts, Helper {
return canWalkOn(new BlockStateInterface(ctx), pos.x, pos.y, pos.z, state); 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) { static boolean canWalkOn(IPlayerContext ctx, BetterBlockPos pos) {
return canWalkOn(new BlockStateInterface(ctx), pos.x, pos.y, pos.z); return canWalkOn(new BlockStateInterface(ctx), pos.x, pos.y, pos.z);
} }
@@ -486,8 +488,8 @@ public interface MovementHelper extends ActionCosts, Helper {
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
BlockPos against1 = placeAt.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]); BlockPos against1 = placeAt.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]);
if (MovementHelper.canPlaceAgainst(ctx, against1)) { if (MovementHelper.canPlaceAgainst(ctx, against1)) {
if (!((Baritone) baritone).getInventoryBehavior().selectThrowawayForLocation(placeAt.getX(), placeAt.getY(), placeAt.getZ())) { // get ready to place a throwaway block 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 or cobble"); Helper.HELPER.logDebug("bb pls get me some blocks. dirt, netherrack, cobble");
state.setStatus(MovementStatus.UNREACHABLE); state.setStatus(MovementStatus.UNREACHABLE);
return PlaceResult.NO_OPTION; return PlaceResult.NO_OPTION;
} }
@@ -513,10 +515,15 @@ public interface MovementHelper extends ActionCosts, Helper {
EnumFacing side = ctx.objectMouseOver().sideHit; EnumFacing side = ctx.objectMouseOver().sideHit;
// only way for selectedBlock.equals(placeAt) to be true is if it's replacable // 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))) { 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 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 { enum PlaceResult {
@@ -198,8 +198,6 @@ public class MovementAscend extends Movement {
return state.setInput(Input.JUMP, true); return state.setInput(Input.JUMP, true);
} }
// System.out.println(flatDistToNext + " " + sideDist);
if (flatDistToNext > 1.2 || sideDist > 0.2) { if (flatDistToNext > 1.2 || sideDist > 0.2) {
return state; return state;
} }
@@ -48,6 +48,9 @@ public class MovementDownward extends Movement {
} }
public static double cost(CalculationContext context, int x, int y, int z) { 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)) { if (!MovementHelper.canWalkOn(context.bsi, x, y - 2, z)) {
return COST_INF; return COST_INF;
} }
@@ -39,7 +39,6 @@ import net.minecraft.init.Items;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i; import net.minecraft.util.math.Vec3i;
@@ -92,8 +91,7 @@ public class MovementFall extends Movement {
targetRotation = new Rotation(toDest.getYaw(), 90.0F); targetRotation = new Rotation(toDest.getYaw(), 90.0F);
RayTraceResult trace = ctx.objectMouseOver(); if (ctx.isLookingAt(dest) || ctx.isLookingAt(dest.down())) {
if (trace != null && trace.typeOfHit == RayTraceResult.Type.BLOCK && (trace.getBlockPos().equals(dest) || trace.getBlockPos().equals(dest.down()))) {
state.setInput(Input.CLICK_RIGHT, true); state.setInput(Input.CLICK_RIGHT, true);
} }
} }
@@ -106,7 +106,9 @@ public class MovementParkour extends Movement {
return; 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.x = x + xDiff * i;
res.y = y; res.y = y;
res.z = z + zDiff * i; res.z = z + zDiff * i;
@@ -208,7 +208,7 @@ public class MovementPillar extends Movement {
return state; return state;
} else { } else {
// Get ready to place a throwaway block // 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); return state.setStatus(MovementStatus.UNREACHABLE);
} }
@@ -30,10 +30,7 @@ import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper; import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState; import baritone.pathing.movement.MovementState;
import baritone.utils.BlockStateInterface; import baritone.utils.BlockStateInterface;
import net.minecraft.block.Block; import net.minecraft.block.*;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.BlockFenceGate;
import net.minecraft.block.BlockSlab;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@@ -151,6 +148,8 @@ public class MovementTraverse extends Movement {
@Override @Override
public MovementState updateState(MovementState state) { public MovementState updateState(MovementState state) {
super.updateState(state); super.updateState(state);
IBlockState pb0 = BlockStateInterface.get(ctx, positionsToBreak[0]);
IBlockState pb1 = BlockStateInterface.get(ctx, positionsToBreak[1]);
if (state.getStatus() != MovementStatus.RUNNING) { if (state.getStatus() != MovementStatus.RUNNING) {
// if the setting is enabled // if the setting is enabled
if (!Baritone.settings().walkWhileBreaking.value) { if (!Baritone.settings().walkWhileBreaking.value) {
@@ -161,10 +160,10 @@ public class MovementTraverse extends Movement {
return state; return state;
} }
// and if it's fine to walk into the blocks in front // 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; return state;
} }
if (MovementHelper.avoidWalkingInto(BlockStateInterface.get(ctx, positionsToBreak[1]).getBlock())) { if (MovementHelper.avoidWalkingInto(pb1.getBlock())) {
return state; return state;
} }
// and we aren't already pressed up against the block // 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 // 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 yawToDest = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), dest), ctx.playerRotations()).getYaw();
float pitchToBreak = state.getTarget().getRotation().get().getPitch(); 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)); state.setTarget(new MovementState.MovementTarget(new Rotation(yawToDest, pitchToBreak), true));
return state.setInput(Input.MOVE_FORWARD, true).setInput(Input.SPRINT, 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(); Block fd = BlockStateInterface.get(ctx, src.down()).getBlock();
boolean ladder = fd == Blocks.LADDER || fd == Blocks.VINE; 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; boolean door = pb0.getBlock() instanceof BlockDoor || pb1.getBlock() instanceof BlockDoor;
if (door) { if (door) {
@@ -234,7 +235,7 @@ public class MovementTraverse extends Movement {
} }
Block low = BlockStateInterface.get(ctx, src).getBlock(); Block low = BlockStateInterface.get(ctx, src).getBlock();
Block high = BlockStateInterface.get(ctx, src.up()).getBlock(); Block high = BlockStateInterface.get(ctx, src.up()).getBlock();
if (!ctx.player().onGround && (low == Blocks.VINE || low == Blocks.LADDER || high == Blocks.VINE || high == Blocks.LADDER)) { if (ctx.player().posY > src.y + 0.1D && !ctx.player().onGround && (low == Blocks.VINE || low == Blocks.LADDER || high == Blocks.VINE || high == Blocks.LADDER)) {
// hitting W could cause us to climb the ladder instead of going forward // hitting W could cause us to climb the ladder instead of going forward
// wait until we're on the ground // wait until we're on the ground
return state; return state;
@@ -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)) { 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); 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)) { IBlockState destDown = BlockStateInterface.get(ctx, dest.down());
new MovementPillar(baritone, dest.down(), dest).updateState(state); // i'm sorry BlockPos against = positionsToBreak[0];
return state; 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; return state;
} else { } else {
wasTheBridgeBlockAlwaysThere = false; wasTheBridgeBlockAlwaysThere = false;
@@ -23,10 +23,7 @@ import baritone.api.pathing.movement.ActionCosts;
import baritone.api.pathing.movement.IMovement; import baritone.api.pathing.movement.IMovement;
import baritone.api.pathing.movement.MovementStatus; import baritone.api.pathing.movement.MovementStatus;
import baritone.api.pathing.path.IPathExecutor; import baritone.api.pathing.path.IPathExecutor;
import baritone.api.utils.BetterBlockPos; import baritone.api.utils.*;
import baritone.api.utils.IPlayerContext;
import baritone.api.utils.RotationUtils;
import baritone.api.utils.VecUtils;
import baritone.api.utils.input.Input; import baritone.api.utils.input.Input;
import baritone.behavior.PathingBehavior; import baritone.behavior.PathingBehavior;
import baritone.pathing.calc.AbstractNodeCostSearch; import baritone.pathing.calc.AbstractNodeCostSearch;
@@ -35,7 +32,6 @@ import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper; import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.movements.*; import baritone.pathing.movement.movements.*;
import baritone.utils.BlockStateInterface; import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import net.minecraft.block.BlockLiquid; import net.minecraft.block.BlockLiquid;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.util.Tuple; import net.minecraft.util.Tuple;
@@ -441,7 +437,10 @@ public class PathExecutor implements IPathExecutor, Helper {
IMovement prev = path.movements().get(pathPosition - 1); IMovement prev = path.movements().get(pathPosition - 1);
if (prev instanceof MovementDescend && prev.getDirection().up().equals(current.getDirection().down())) { if (prev instanceof MovementDescend && prev.getDirection().up().equals(current.getDirection().down())) {
BlockPos center = current.getSrc().up(); 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); behavior.baritone.getInputOverrideHandler().setInputForceState(Input.JUMP, false);
return true; return true;
} }
@@ -566,7 +565,10 @@ public class PathExecutor implements IPathExecutor, Helper {
if (next instanceof MovementDescend && next.getDirection().equals(current.getDirection())) { if (next instanceof MovementDescend && next.getDirection().equals(current.getDirection())) {
return true; 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 true;
} }
return next instanceof MovementDiagonal && Baritone.settings().allowOvershootDiagonalDescend.value; return next instanceof MovementDiagonal && Baritone.settings().allowOvershootDiagonalDescend.value;
@@ -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.AirSchematic;
import baritone.utils.schematic.Schematic; import baritone.utils.schematic.Schematic;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack; 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 class BuilderProcess extends BaritoneProcessHelper implements IBuilderProcess {
public BuilderProcess(Baritone baritone) {
super(baritone);
}
private HashSet<BetterBlockPos> incorrectPositions; private HashSet<BetterBlockPos> incorrectPositions;
private String name; private String name;
private ISchematic realSchematic;
private ISchematic schematic; private ISchematic schematic;
private Vec3i origin; private Vec3i origin;
private int ticks; private int ticks;
private boolean paused;
private int layer;
public boolean build(String schematicFile, BlockPos origin) { public BuilderProcess(Baritone baritone) {
File file = new File(new File(Minecraft.getMinecraft().gameDir, "schematics"), schematicFile); super(baritone);
System.out.println(file + " " + file.exists());
return build(schematicFile, file, origin);
} }
@Override @Override
public void build(String name, ISchematic schematic, Vec3i origin) { public void build(String name, ISchematic schematic, Vec3i origin) {
this.name = name; this.name = name;
this.schematic = schematic; this.schematic = schematic;
this.realSchematic = null;
this.origin = origin; this.origin = origin;
this.paused = false;
this.layer = 0;
}
public void resume() {
paused = false;
}
public void pause() {
paused = true;
} }
@Override @Override
@@ -154,10 +161,10 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
} }
public class Placement { public class Placement {
final int hotbarSelection; private final int hotbarSelection;
final BlockPos placeAgainst; private final BlockPos placeAgainst;
final EnumFacing side; private final EnumFacing side;
final Rotation rot; private final Rotation rot;
public Placement(int hotbarSelection, BlockPos placeAgainst, EnumFacing side, Rotation rot) { public Placement(int hotbarSelection, BlockPos placeAgainst, EnumFacing side, Rotation rot) {
this.hotbarSelection = hotbarSelection; 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; 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)}; return new Vec3d[]{new Vec3d(x, 0.25, z), new Vec3d(x, 0.75, z)};
default: // null default: // null
throw new NullPointerException(); throw new IllegalStateException();
} }
} }
@Override @Override
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { 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)) { if (baritone.getInputOverrideHandler().isInputForcedDown(Input.CLICK_LEFT)) {
ticks = 5; ticks = 5;
} else { } else {
ticks--; ticks--;
} }
Optional<Tuple<BetterBlockPos, Rotation>> toBreak = toBreakNearPlayer(bcc);
baritone.getInputOverrideHandler().clearAllKeys(); 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) { if (toBreak.isPresent() && isSafeToCancel && ctx.player().onGround) {
// we'd like to pause to break this block // 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 // 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 // and is unable since it's unsneaked in the intermediary tick
baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, true); 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); 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<>(); List<IBlockState> desirableOnHotbar = new ArrayList<>();
Optional<Placement> toPlace = searchForPlacables(bcc, desirableOnHotbar); Optional<Placement> toPlace = searchForPlacables(bcc, desirableOnHotbar);
@@ -322,10 +367,10 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
baritone.getLookBehavior().updateTarget(rot, true); baritone.getLookBehavior().updateTarget(rot, true);
ctx.player().inventory.currentItem = toPlace.get().hotbarSelection; ctx.player().inventory.currentItem = toPlace.get().hotbarSelection;
baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, true); 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); 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); List<IBlockState> approxPlacable = placable(36);
@@ -359,9 +404,9 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
if (goal == null) { if (goal == null) {
goal = assemble(bcc, approxPlacable); // we're far away, so assume that we have our whole inventory to recalculate placable properly goal = assemble(bcc, approxPlacable); // we're far away, so assume that we have our whole inventory to recalculate placable properly
if (goal == null) { if (goal == null) {
logDirect("Unable to do it =("); logDirect("Unable to do it. Pausing. resume to resume, cancel to cancel");
onLostControl(); paused = true;
return null; return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
} }
} }
return new PathingCommandContext(goal, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH, bcc); 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 y = 0; y < schematic.heightY(); y++) {
for (int z = 0; z < schematic.lengthZ(); z++) { for (int z = 0; z < schematic.lengthZ(); z++) {
for (int x = 0; x < schematic.widthX(); x++) { for (int x = 0; x < schematic.widthX(); x++) {
if (schematic.inSchematic(x, y, z)) { if (schematic.inSchematic(x, y, z) && !valid(bcc.bsi.get0(x + origin.getX(), y + origin.getY(), z + origin.getZ()), schematic.desiredState(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()));
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 { public static class GoalAdjacent extends GoalGetToBlock {
boolean allowSameLevel; private boolean allowSameLevel;
public GoalAdjacent(BlockPos pos, boolean allowSameLevel) { public GoalAdjacent(BlockPos pos, boolean allowSameLevel) {
super(pos); super(pos);
@@ -540,11 +583,14 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
incorrectPositions = null; incorrectPositions = null;
name = null; name = null;
schematic = null; schematic = null;
realSchematic = null;
layer = 0;
paused = false;
} }
@Override @Override
public String displayName0() { public String displayName0() {
return "Building " + name; return paused ? "Builder Paused" : "Building " + name;
} }
public List<IBlockState> placable(int size) { 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()))) { if (this.goal == null || (this.goal.isInGoal(ctx.playerFeet()) && this.goal.isInGoal(baritone.getPathingBehavior().pathStart()))) {
onLostControl(); // we're there xd 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.CANCEL_AND_SET_GOAL);
} }
return new PathingCommand(this.goal, PathingCommandType.SET_GOAL_AND_PATH); return new PathingCommand(this.goal, PathingCommandType.SET_GOAL_AND_PATH);
@@ -19,17 +19,33 @@ package baritone.process;
import baritone.Baritone; import baritone.Baritone;
import baritone.api.cache.ICachedWorld; 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.pathing.goals.GoalXZ;
import baritone.api.process.IExploreProcess;
import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommand;
import baritone.api.process.PathingCommandType; import baritone.api.process.PathingCommandType;
import baritone.api.utils.MyChunkPos;
import baritone.cache.CachedWorld; import baritone.cache.CachedWorld;
import baritone.utils.BaritoneProcessHelper; 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.BlockPos;
import net.minecraft.util.math.ChunkPos;
public class ExploreProcess extends BaritoneProcessHelper { 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 implements IExploreProcess {
private BlockPos explorationOrigin; private BlockPos explorationOrigin;
private IChunkFilter filter;
public ExploreProcess(Baritone baritone) { public ExploreProcess(Baritone baritone) {
super(baritone); super(baritone);
} }
@@ -39,10 +55,26 @@ public class ExploreProcess extends BaritoneProcessHelper {
return explorationOrigin != null; return explorationOrigin != null;
} }
@Override
public void explore(int centerX, int centerZ) { public void explore(int centerX, int centerZ) {
explorationOrigin = new BlockPos(centerX, 0, 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 @Override
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
if (calcFailed) { if (calcFailed) {
@@ -50,41 +82,165 @@ public class ExploreProcess extends BaritoneProcessHelper {
onLostControl(); onLostControl();
return null; return null;
} }
BlockPos closestUncached = closestUncachedChunk(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) { if (closestUncached == null) {
logDebug("awaiting region load from disk"); logDebug("awaiting region load from disk");
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); 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);
return new PathingCommand(new GoalXZ(closestUncached.getX(), closestUncached.getZ()), PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH);
} }
private BlockPos closestUncachedChunk(BlockPos pos) { private Goal[] closestUncachedChunks(BlockPos center, IChunkFilter filter) {
int chunkX = pos.getX() >> 4; int chunkX = center.getX() >> 4;
int chunkZ = pos.getZ() >> 4; int chunkZ = center.getZ() >> 4;
ICachedWorld cache = baritone.getWorldProvider().getCurrentWorld().getCachedWorld();
for (int dist = 0; ; dist++) { for (int dist = 0; ; dist++) {
List<BlockPos> centers = new ArrayList<>();
for (int dx = -dist; dx <= dist; dx++) { for (int dx = -dist; dx <= dist; dx++) {
for (int dz = -dist; dz <= dist; dz++) { for (int dz = -dist; dz <= dist; dz++) {
int trueDist = Baritone.settings().exploreUsePythagorean.value ? dx * dx + dz + dz : Math.abs(dx) + Math.abs(dz); int trueDist = Baritone.settings().exploreUsePythagorean.value ? dx * dx + dz * dz : Math.abs(dx) + Math.abs(dz);
if (trueDist != dist) { if (trueDist != dist) {
continue; // not considering this one just yet in our expanding search 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 centerX = (chunkX + dx) * 16 + 8;
int centerZ = (chunkZ + dz) * 18 + 8; int centerZ = (chunkZ + dz) * 18 + 8;
int offset = 16 * Baritone.settings().worldExploringChunkOffset.value;
if (cache.isCached(centerX, centerZ)) { if (dx < 0) {
continue; centerX -= offset;
} else {
centerX += offset;
} }
if (!((CachedWorld) cache).regionLoaded(centerX, centerZ)) { if (dz < 0) {
Baritone.getExecutor().execute(() -> { centerZ -= offset;
((CachedWorld) cache).tryLoadFromDisk(centerX >> 9, centerZ >> 9); } else {
}); centerZ += offset;
return null; // we still need to load regions from disk in order to decide properly
} }
return new BlockPos(centerX, 0, centerZ); centers.add(new BlockPos(centerX, 0, centerZ));
} }
} }
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();
} }
} }
@@ -95,6 +251,6 @@ public class ExploreProcess extends BaritoneProcessHelper {
@Override @Override
public String displayName0() { public String displayName0() {
return "Exploring around " + explorationOrigin + ", currently going to " + closestUncachedChunk(explorationOrigin); return "Exploring around " + explorationOrigin + ", currently going to " + new GoalComposite(closestUncachedChunks(explorationOrigin, calcFilter()));
} }
} }
@@ -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";
}
}
@@ -102,7 +102,7 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
@Override @Override
public String displayName0() { public String displayName0() {
return "Follow " + cache; return "Following " + cache;
} }
@Override @Override
@@ -117,7 +117,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
} }
// blacklist the closest block and its adjacent blocks // blacklist the closest block and its adjacent blocks
public synchronized void blacklistClosest() { public synchronized boolean blacklistClosest() {
List<BlockPos> newBlacklist = new ArrayList<>(); List<BlockPos> newBlacklist = new ArrayList<>();
knownLocations.stream().min(Comparator.comparingDouble(ctx.player()::getDistanceSq)).ifPresent(newBlacklist::add); knownLocations.stream().min(Comparator.comparingDouble(ctx.player()::getDistanceSq)).ifPresent(newBlacklist::add);
outer: outer:
@@ -140,6 +140,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
} }
logDebug("Blacklisting unreachable locations " + newBlacklist); logDebug("Blacklisting unreachable locations " + newBlacklist);
blacklist.addAll(newBlacklist); blacklist.addAll(newBlacklist);
return !newBlacklist.isEmpty();
} }
// safer than direct double comparison from distanceSq // safer than direct double comparison from distanceSq
+87 -17
View File
@@ -22,16 +22,20 @@ import baritone.api.pathing.goals.*;
import baritone.api.process.IMineProcess; import baritone.api.process.IMineProcess;
import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommand;
import baritone.api.process.PathingCommandType; import baritone.api.process.PathingCommandType;
import baritone.api.utils.BlockUtils;
import baritone.api.utils.IPlayerContext; import baritone.api.utils.IPlayerContext;
import baritone.api.utils.Rotation;
import baritone.api.utils.RotationUtils; import baritone.api.utils.RotationUtils;
import baritone.api.utils.input.Input;
import baritone.cache.CachedChunk; import baritone.cache.CachedChunk;
import baritone.cache.ChunkPacker;
import baritone.cache.WorldScanner; import baritone.cache.WorldScanner;
import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.MovementHelper; import baritone.pathing.movement.MovementHelper;
import baritone.utils.BaritoneProcessHelper; import baritone.utils.BaritoneProcessHelper;
import baritone.utils.BlockStateInterface; import baritone.utils.BlockStateInterface;
import net.minecraft.block.Block; 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.Entity;
import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.item.EntityItem;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
@@ -81,26 +85,48 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
return null; return null;
} }
} }
boolean shouldCancel = calcFailed;
if (calcFailed && !knownOreLocations.isEmpty() && Baritone.settings().blacklistClosestOnFailure.value) { if (calcFailed && !knownOreLocations.isEmpty() && Baritone.settings().blacklistClosestOnFailure.value) {
logDirect("Unable to find any path to " + mining + ", blacklisting presumably unreachable closest instance..."); 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); knownOreLocations.removeIf(blacklist::contains);
calcFailed = false; // 😎 shouldCancel = false; // 😎
} }
if (calcFailed) { if (shouldCancel) {
logDirect("Unable to find any path to " + mining + ", canceling Mine"); logDirect("Unable to find any path to " + mining + ", canceling Mine");
cancel(); cancel();
return null; return null;
} }
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.value; int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.value;
List<BlockPos> curr = new ArrayList<>(knownOreLocations);
if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain
List<BlockPos> curr = new ArrayList<>(knownOreLocations);
CalculationContext context = new CalculationContext(baritone, true); CalculationContext context = new CalculationContext(baritone, true);
Baritone.getExecutor().execute(() -> rescan(curr, context)); Baritone.getExecutor().execute(() -> rescan(curr, context));
} }
if (Baritone.settings().legitMine.value) { if (Baritone.settings().legitMine.value) {
addNearby(); 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(); PathingCommand command = updateGoal();
if (command == null) { if (command == null) {
// none in range // none in range
@@ -177,15 +203,63 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
knownOreLocations = locs; 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) { private static Goal coalesce(IPlayerContext ctx, BlockPos loc, List<BlockPos> locs) {
if (!Baritone.settings().forceInternalMining.value) { 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) @Override
boolean upwardGoal = locs.contains(loc.up()) || (Baritone.settings().internalMiningAirException.value && BlockStateInterface.getBlock(ctx, loc.up()) == Blocks.AIR); public boolean isInGoal(int x, int y, int z) {
boolean downwardGoal = locs.contains(loc.down()) || (Baritone.settings().internalMiningAirException.value && BlockStateInterface.getBlock(ctx, loc.down()) == Blocks.AIR); return x == this.x && (y == this.y || y == this.y - 1 || y == this.y - 2) && z == this.z;
return upwardGoal == downwardGoal ? new GoalTwoBlocks(loc) : upwardGoal ? new GoalBlock(loc) : new GoalBlock(loc.down()); }
@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) { 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) { public static List<BlockPos> searchWorld(CalculationContext ctx, List<Block> mining, int max, List<BlockPos> alreadyKnown, List<BlockPos> blacklist) {
List<BlockPos> locs = new ArrayList<>(); List<BlockPos> locs = new ArrayList<>();
List<Block> uninteresting = new ArrayList<>(); List<Block> uninteresting = new ArrayList<>();
//long b = System.currentTimeMillis();
for (Block m : mining) { for (Block m : mining) {
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(m)) { if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(m)) {
// maxRegionDistanceSq 2 means adjacent directly or adjacent diagonally; nothing further than that // 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 { } else {
uninteresting.add(m); uninteresting.add(m);
} }
} }
locs = prune(ctx, locs, mining, max, blacklist); locs = prune(ctx, locs, mining, max, blacklist);
//System.out.println("Scan of cached chunks took " + (System.currentTimeMillis() - b) + "ms"); if (locs.isEmpty() || (Baritone.settings().extendCacheOnThreshold.value && locs.size() < max)) {
if (locs.isEmpty()) {
uninteresting = mining; uninteresting = mining;
} }
if (!uninteresting.isEmpty()) { if (!uninteresting.isEmpty()) {
//long before = System.currentTimeMillis();
locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(ctx.getBaritone().getPlayerContext(), uninteresting, max, 10, 32)); // maxSearchRadius is NOT sq 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); locs.addAll(alreadyKnown);
return prune(ctx, locs, mining, max, blacklist); return prune(ctx, locs, mining, max, blacklist);
@@ -302,7 +372,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
@Override @Override
public void mineByName(int quantity, String... blocks) { public void mineByName(int quantity, String... blocks) {
mine(quantity, blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(ChunkPacker::stringToBlock).toArray(Block[]::new)); mine(quantity, blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(BlockUtils::stringToBlockRequired).toArray(Block[]::new));
} }
@Override @Override
@@ -22,6 +22,7 @@ import baritone.api.event.events.TickEvent;
import baritone.api.event.listener.AbstractGameEventListener; import baritone.api.event.listener.AbstractGameEventListener;
import baritone.api.pathing.goals.Goal; import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalBlock; import baritone.api.pathing.goals.GoalBlock;
import baritone.api.utils.Helper;
import baritone.api.utils.IPlayerContext; import baritone.api.utils.IPlayerContext;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiMainMenu; import net.minecraft.client.gui.GuiMainMenu;
@@ -19,6 +19,7 @@ package baritone.utils;
import baritone.Baritone; import baritone.Baritone;
import baritone.api.process.IBaritoneProcess; import baritone.api.process.IBaritoneProcess;
import baritone.api.utils.Helper;
import baritone.api.utils.IPlayerContext; import baritone.api.utils.IPlayerContext;
public abstract class BaritoneProcessHelper implements IBaritoneProcess, Helper { public abstract class BaritoneProcessHelper implements IBaritoneProcess, Helper {
@@ -17,6 +17,7 @@
package baritone.utils; package baritone.utils;
import baritone.api.utils.Helper;
import baritone.api.utils.IPlayerContext; import baritone.api.utils.IPlayerContext;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand; import net.minecraft.util.EnumHand;
@@ -18,6 +18,7 @@
package baritone.utils; package baritone.utils;
import baritone.Baritone; import baritone.Baritone;
import baritone.api.utils.Helper;
import baritone.api.utils.IPlayerContext; import baritone.api.utils.IPlayerContext;
import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand; import net.minecraft.util.EnumHand;
@@ -46,6 +47,9 @@ public class BlockPlaceHelper implements Helper {
ctx.player().swingArm(hand); ctx.player().swingArm(hand);
return; return;
} }
if (!ctx.player().getHeldItem(hand).isEmpty() && ctx.playerController().processRightClick(ctx.player(), ctx.world(), hand) == EnumActionResult.SUCCESS) {
return;
}
} }
} }
} }
@@ -87,7 +87,6 @@ public class GuiClick extends GuiScreen {
clickStart = null; clickStart = null;
} }
@Override @Override
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) { protected void mouseClicked(int mouseX, int mouseY, int mouseButton) {
clickStart = currentMouseOver; clickStart = currentMouseOver;
@@ -120,8 +119,6 @@ public class GuiClick extends GuiScreen {
GlStateManager.disableBlend(); GlStateManager.disableBlend();
} }
} }
} }
public Vec3d toWorld(double x, double y, double z) { public Vec3d toWorld(double x, double y, double z) {
+11 -10
View File
@@ -23,6 +23,7 @@ import baritone.api.event.events.RenderEvent;
import baritone.api.pathing.calc.IPath; import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.*; import baritone.api.pathing.goals.*;
import baritone.api.utils.BetterBlockPos; import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Helper;
import baritone.api.utils.interfaces.IGoalRenderPos; import baritone.api.utils.interfaces.IGoalRenderPos;
import baritone.behavior.PathingBehavior; import baritone.behavior.PathingBehavior;
import baritone.pathing.path.PathExecutor; import baritone.pathing.path.PathExecutor;
@@ -83,17 +84,22 @@ public final class PathRenderer implements Helper {
if (goal != null && Baritone.settings().renderGoal.value) { if (goal != null && Baritone.settings().renderGoal.value) {
drawDankLitGoalBox(renderView, goal, partialTicks, Baritone.settings().colorGoalBox.value); drawDankLitGoalBox(renderView, goal, partialTicks, Baritone.settings().colorGoalBox.value);
} }
if (!Baritone.settings().renderPath.value) { if (!Baritone.settings().renderPath.value) {
return; 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); //drawManySelectionBoxes(player, Collections.singletonList(behavior.pathStart()), partialTicks, Color.WHITE);
//long start = System.nanoTime(); //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 // Render the current path, if there is one
if (current != null && current.getPath() != null) { if (current != null && current.getPath() != null) {
int renderBegin = Math.max(current.getPosition() - 3, 0); int renderBegin = Math.max(current.getPosition() - 3, 0);
@@ -104,11 +110,6 @@ public final class PathRenderer implements Helper {
} }
//long split = System.nanoTime(); //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 // If there is a path calculation currently running, render the path calculation process
behavior.getInProgress().ifPresent(currentlyRunning -> { 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); 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(); tessellator.draw();
} }
if (Baritone.settings().renderPathIgnoreDepth.value) { if (Baritone.settings().renderPathIgnoreDepth.value) {
@@ -187,7 +188,7 @@ public final class PathRenderer implements Helper {
GlStateManager.disableBlend(); 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 d0 = mc.getRenderManager().viewerPosX;
double d1 = mc.getRenderManager().viewerPosY; double d1 = mc.getRenderManager().viewerPosY;
double d2 = mc.getRenderManager().viewerPosZ; double d2 = mc.getRenderManager().viewerPosZ;
@@ -92,8 +92,8 @@ public class PathingControlManager implements IPathingControlManager {
p.secretInternalSetGoal(null); p.secretInternalSetGoal(null);
return; return;
} }
if (inControlThisTick != inControlLastTick && command.commandType != PathingCommandType.REQUEST_PAUSE) { if (inControlThisTick != inControlLastTick && command.commandType != PathingCommandType.REQUEST_PAUSE && inControlLastTick != null && !inControlLastTick.isTemporary()) {
// if control has changed, and the new process wants to do something // if control has changed from a real process to another real process, and the new process wants to do something
p.cancelSegmentIfSafe(); p.cancelSegmentIfSafe();
// get rid of the in progress stuff from the last process // 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()); PathingCommand exec = proc.onTick(Objects.equals(proc, inControlLastTick) && baritone.getPathingBehavior().calcFailedLastTick(), baritone.getPathingBehavior().isSafeToCancel());
if (exec == null) { if (exec == null) {
if (proc.isActive()) { if (proc.isActive()) {
throw new IllegalStateException(proc.displayName() + " returned null PathingCommand"); throw new IllegalStateException(proc.displayName() + " actively returned null PathingCommand");
} }
proc.onLostControl(); // no need to call onLostControl; they are reporting inactive.
} else { } else if (exec.commandType != PathingCommandType.DEFER) {
inControlThisTick = proc; inControlThisTick = proc;
if (!proc.isTemporary()) { if (!proc.isTemporary()) {
iterator.forEachRemaining(IBaritoneProcess::onLostControl); iterator.forEachRemaining(IBaritoneProcess::onLostControl);
@@ -19,6 +19,7 @@ package baritone.utils.pathing;
import baritone.api.pathing.calc.IPath; import baritone.api.pathing.calc.IPath;
import baritone.api.utils.BetterBlockPos; import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Helper;
import baritone.api.utils.IPlayerContext; import baritone.api.utils.IPlayerContext;
import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.CalculationContext;
import it.unimi.dsi.fastutil.longs.Long2DoubleOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2DoubleOpenHashMap;
@@ -31,7 +32,7 @@ public final class Favoring {
for (Avoidance avoid : Avoidance.create(ctx)) { for (Avoidance avoid : Avoidance.create(ctx)) {
avoid.applySpherical(favorings); 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 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.BaritoneAPI;
import baritone.api.cache.IWorldData; import baritone.api.cache.IWorldData;
import baritone.api.utils.Helper;
import baritone.api.utils.IPlayerContext; import baritone.api.utils.IPlayerContext;
import baritone.api.utils.IPlayerController; import baritone.api.utils.IPlayerController;
import baritone.api.utils.RayTraceUtils; import baritone.api.utils.RayTraceUtils;
import baritone.utils.Helper;
import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World; import net.minecraft.world.World;
@@ -17,8 +17,8 @@
package baritone.utils.player; package baritone.utils.player;
import baritone.api.utils.Helper;
import baritone.api.utils.IPlayerController; import baritone.api.utils.IPlayerController;
import baritone.utils.Helper;
import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.multiplayer.WorldClient; import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
@@ -72,4 +72,9 @@ public enum PrimaryPlayerController implements IPlayerController, Helper {
// primaryplayercontroller is always in a WorldClient so this is ok // primaryplayercontroller is always in a WorldClient so this is ok
return mc.playerController.processRightClickBlock(player, (WorldClient) world, pos, direction, vec, hand); return mc.playerController.processRightClickBlock(player, (WorldClient) world, pos, direction, vec, hand);
} }
@Override
public EnumActionResult processRightClick(EntityPlayerSP player, World world, EnumHand hand) {
return mc.playerController.processRightClick(player, world, hand);
}
} }