Compare commits

..

289 Commits

Author SHA1 Message Date
Leijurv
1a4635df16 v1.3.3 2019-07-11 12:47:44 -07:00
Leijurv
1390af20b6 fix parkour and multithread farm 2019-07-11 12:46:24 -07:00
Leijurv
1427cf57a8 randomlooking 2019-07-11 11:56:44 -07:00
Leijurv
d70243b4c0 leijurv would never do this 2019-07-11 11:08:45 -07:00
Leijurv
8f63dd4ba6 Merge branch 'master' into 1.13.2 2019-07-11 10:51:29 -07:00
Leijurv
01658286af detect allowbreak false 2019-07-11 10:41:24 -07:00
Leijurv
aa90c8b7cd address encapsulation conccerns 2019-07-10 22:18:11 -07:00
Leijurv
eba1011fd6 remove scuff 2019-07-09 23:47:42 -07:00
Brady
96a424c25a Merge pull request #445 from SylveonBottle/patch-1
Speed up production
2019-07-09 14:23:37 -05:00
Leijurv
f4dd100345 fix indexof 2019-07-08 23:16:26 -07:00
Brady
c7e1c917c3 Fix Baritone thinking it can walk through wall-placed skulls
Fixes #485
2019-07-08 19:21:09 -05:00
Leijurv
cd4205c361 v1.2.7 2019-07-07 12:07:00 -07:00
Leijurv
b81bcf8c6d fix path start in diagonal and downward 2019-07-07 11:44:56 -07:00
Leijurv
4259764b70 thank you off by one errors very cool 2019-07-07 11:12:32 -07:00
Leijurv
8f761f7dff better skip ahead 2019-07-07 11:03:43 -07:00
Leijurv
cbbaf2aa2f unscuff 2019-07-06 20:38:59 -07:00
Leijurv
dd9b84646a disgraceful 2019-07-06 17:07:16 -07:00
Leijurv
94131fd705 too many newlines 2019-07-05 21:19:18 -07:00
Leijurv
6d8914e6c9 spell it out even more 2019-07-04 15:52:09 -07:00
Leijurv
63ee687cee shill EVEN harder 2019-07-03 23:47:47 -07:00
Leijurv
ab779dc850 increase shilling 2019-07-02 22:13:17 -07:00
Leijurv
c2f35ae46f dawn of the final month 2019-07-01 10:21:58 -07:00
Leijurv
199e0e5ed3 better comparison 2019-06-30 21:55:32 -07:00
Leijurv
a8155b4b0b privatize 2019-06-29 11:56:02 -07:00
Leijurv
fdd78cf110 codcacy wants these to be combined 2019-06-28 22:17:31 -07:00
Leijurv
afff6395d1 codcacy wants a default 2019-06-27 21:02:44 -07:00
Leijurv
4d3d48e962 crucial documentation oversight 2019-06-26 23:58:22 -07:00
Leijurv
36290e4e53 crucial encapsulation improvement 2019-06-25 22:54:24 -07:00
Leijurv
fd6923dd28 ok i forgot falling into water 2019-06-24 20:38:17 -07:00
Leijurv
9c64067d49 vastly improve resilience to lagbacks, fixes #446 2019-06-24 17:53:25 -07:00
Leijurv
f4d2ea7923 fix path canceling at edge of loaded chunks hopefully 2019-06-24 10:43:49 -07:00
Leijurv
ce3d3bb244 literally no reason to have this 2019-06-23 22:49:33 -07:00
Leijurv
fa71e7d84f reduce stupidity 2019-06-22 21:11:09 -07:00
Leijurv
b0115b8b4c Merge pull request #447 from babbaj/master
daily commit
2019-06-21 23:59:32 -07:00
Babbaj
3902b2db3b increase line count and improve readability 2019-06-21 23:01:37 -04:00
SylveonBottle
4ff61f96df wow times infinity 2019-06-21 03:59:10 -05:00
Leijurv
f998dce614 wow wow 2019-06-20 23:48:02 -07:00
Leijurv
2b9084d2f3 wow 2019-06-19 20:41:21 -07:00
Leijurv
b3605546ac golly another missing slash wow 2019-06-18 23:15:47 -07:00
Leijurv
96097ab726 this counts as a commit 2019-06-17 22:44:38 -07:00
Leijurv
be142d79bc link to the code 2019-06-16 23:06:57 -07:00
Leijurv
0fd241a9ba crucial performance optimization 2019-06-15 11:04:05 -07:00
Leijurv
7b192f17e8 privatize 2019-06-14 21:42:11 -07:00
Leijurv
cc015846d2 explain 2019-06-13 23:13:40 -07:00
Leijurv
e785bd13f5 sanity check 2019-06-12 16:41:05 -07:00
Leijurv
eb6c0a39ea codacy wants this 2019-06-11 23:46:04 -07:00
Leijurv
86525f98ec fix scuffed jumping, fixes #426 2019-06-10 23:12:37 -07:00
Leijurv
125facfbb6 Merge branch 'master' into 1.13.2 2019-06-10 11:50:14 -07:00
Leijurv
94bf703dde this counts as a commit 2019-06-09 23:56:54 -07:00
Leijurv
14bb0a0a80 alt text 2019-06-08 23:13:27 -07:00
Leijurv
1ee6e04f00 this counts as a commit 2019-06-07 21:29:31 -07:00
Brady
ee6796d5e2 crucial performance optimization (pt. 2) 2019-06-07 03:52:46 -05:00
Brady
81d7f3c319 crucial performance optimization 2019-06-07 03:19:23 -05:00
Leijurv
9822962d98 it is tbh 2019-06-06 23:55:12 -07:00
Brady
ce606f826b consistency 2019-06-06 19:05:13 -05:00
Brady
4c4bc8058b Some clean ups 2019-06-06 04:15:43 -05:00
Leijurv
f0210f7c5f add an additional underscore 2019-06-05 22:12:28 -07:00
Leijurv
aef84eceb8 fix a rare crash when the view is occluded by falling sand, fixes #443 2019-06-05 14:26:26 -07:00
Leijurv
a6ea9ed3a6 👶 2019-06-05 12:47:18 -07:00
Leijurv
0815e3c195 thank u intellij very cool suggestion 2019-06-05 12:08:19 -07:00
Leijurv
a1c03eb601 another tool selection fix 2019-06-05 12:04:09 -07:00
Leijurv
1e43563cc3 fix weird backfill behavior 2019-06-04 20:55:31 -07:00
Leijurv
63f3f9123a Merge pull request #409 from babbaj/master
use ImmutableSet
2019-06-03 22:17:14 -07:00
Leijurv
4860d3bd18 Merge pull request #439 from ImpcatDevelopment/delete-user-defined-waypoints
Added the command delete. Allows you to remove a user defined waypoint.
2019-06-03 22:09:08 -07:00
0x22
7fa6593bdc Added the command delete. Allows you to remove a user defined waypoint. Fixes #334 2019-06-04 01:04:13 -04:00
Leijurv
e1dd580df8 fix improper singleplayer check after quitting singleplayer 2019-06-03 15:27:24 -07:00
Leijurv
f19e63d6e9 mc version support is important 2019-06-03 13:43:32 -07:00
Leijurv
130873d91d 1.13.2 2019-06-02 21:33:10 -07:00
Leijurv
9611cb9057 1.13.2 is supported 2019-06-01 17:54:16 -07:00
Leijurv
023aa78d8b yay 2019-06-01 15:36:52 -07:00
Leijurv
39a231eae0 crucial performance optimization 2019-06-01 10:56:24 -07:00
Leijurv
aca6922be0 there is no actual integration 2019-05-31 23:01:16 -07:00
Leijurv
1a52537d0c badges 2019-05-30 20:49:04 -08:00
Leijurv
479b4e3349 releases download count 2019-05-29 10:45:59 -07:00
Leijurv
a1e2b018a2 very good suggestion 2019-05-28 14:17:54 -07:00
Leijurv
aa0f664cda just for debugging purposes 😉 2019-05-27 22:48:06 -07:00
Brady
2e2f4aee1b critical performance enhancement 2019-05-27 02:31:28 -05:00
Leijurv
18474d872c unused 2019-05-26 12:14:08 -07:00
Leijurv
44327c009a Merge pull request #427 from babbaj/master
yet another meaningless commit
2019-05-25 14:30:10 -07:00
Babbaj
de554655a5 yet another meaningless commit 2019-05-25 17:27:06 -04:00
Babbaj
bd0c7b9391 yet another meaningless commit 2019-05-25 17:25:23 -04:00
Babbaj
8d32db5206 Merge branch 'master' of https://github.com/cabaletta/baritone 2019-05-25 17:23:47 -04:00
Leijurv
a6954aa719 bye 2 2019-05-24 10:36:01 -07:00
Leijurv
b4d203ab99 bye 2019-05-23 20:47:22 -08:00
Leijurv
bb924ad83f thank you intellij very cool 2019-05-22 23:41:02 -07:00
Leijurv
79da32cc60 unused 2019-05-21 15:07:05 -07:00
Leijurv
c7fe9c3171 finalize 2019-05-20 22:37:51 -07:00
Leijurv
d70da4f37d finalize these 2019-05-19 21:53:09 -08:00
Leijurv
ccc1b04e81 crucial spacing 2019-05-18 17:11:16 -07:00
Leijurv
352e428890 explicitly set serialized name post obf 2019-05-17 22:21:40 -08:00
Leijurv
4679e12588 better usage 2019-05-16 15:20:52 -07:00
Leijurv
16b74ff53c v1.3.2 2019-05-16 14:57:26 -07:00
Leijurv
9297e98ac3 Merge branch 'master' into 1.13.2 2019-05-16 14:55:37 -07:00
Leijurv
6861bfd4e6 relative goals 2019-05-16 11:50:48 -07:00
Leijurv
0dd4834e18 add explanation 2019-05-15 21:55:01 -08:00
Leijurv
da58988f01 build in layers order 2019-05-14 16:03:11 -07:00
Leijurv
b2f3880722 add todo 2019-05-13 20:13:22 -08:00
Leijurv
0293a76702 less yikes 2019-05-12 23:25:50 -07:00
Leijurv
6a13e94c4f warning 2019-05-11 21:13:46 -07:00
Leijurv
79d448e5f4 add crucial explanation 2019-05-10 23:55:50 -07:00
Leijurv
264b3db63c this counts as a commit 2019-05-09 15:20:37 -07:00
Brady
c8cd4b5f28 Merge pull request #410 from SuperOP535/patch-2
Automatic CRLF -> LF normalization
2019-05-09 11:49:05 -05:00
Leijurv
c9e81897a5 im blind lol thanks babj 2019-05-08 11:51:48 -07:00
Leijurv
c738007538 epic label 2019-05-07 21:40:03 -08:00
Leijurv
da8bf6b1b3 fix a potential concurrency issue 2019-05-06 14:07:46 -07:00
Leijurv
1501d721e7 build repeat vector 2019-05-06 14:01:01 -07:00
Leijurv
482d874af2 this counts as a commit 2019-05-05 23:57:56 -07:00
Leijurv
7dcd7384f1 allow overshooting traverse 2019-05-04 15:01:11 -07:00
Leijurv
2a5ef35794 move this down to the other render settings 2019-05-03 11:44:37 -07:00
Leijurv
0f09a46540 javadoc 2019-05-02 23:03:15 -07:00
Leijurv
a6d4708ccf Merge pull request #412 from EvilSourcerer/master
render dank lit boxes for goalYLevel
2019-05-02 23:02:25 -07:00
evilsourcerer
77303b4a62 render boxes for goalYLevel 2019-05-03 01:48:37 -04:00
Leijurv
0ffbb0c151 quiet 2019-05-02 11:47:35 -07:00
Leijurv
b521d7bee1 fix dummy merge typo 2019-05-02 11:42:49 -07:00
Leijurv
4e96c5e5ee Merge branch 'master' into 1.13.2 2019-05-01 23:12:19 -07:00
Leijurv
e05010c9d2 fix weird oscillation when mining large veins 2019-05-01 23:07:20 -07:00
Leijurv
d0a1c241a4 replace liquid source blocks in builder 2019-05-01 14:03:36 -07:00
Leijurv
4ea8f23fc7 fix typo crash, fixes #406 2019-05-01 12:22:47 -07:00
Leijurv
ec819220b7 Merge branch 'master' into 1.13.2 2019-05-01 12:15:31 -07:00
Leijurv
54da0d24a3 dont mine blocks that update falling blocks, fixes #395 2019-05-01 11:16:24 -07:00
Leijurv
58ebd5f9a6 split this out into its own function 2019-05-01 11:01:00 -07:00
Leijurv
d60a0bee9e move this behind the toolset cache for performance 2019-05-01 10:48:17 -07:00
Leijurv
e9e26c981a fine babj 2019-05-01 10:37:23 -07:00
SuperOP535
5f12f04e87 Automatic CRLF -> LF normalization 2019-05-01 14:05:47 +02:00
Leijurv
7b7be32ca7 also break passable blocks at foot level like mushrooms, fixes #407 2019-04-30 23:24:08 -07:00
Leijurv
a14166b1e2 overhaul to usage 2019-04-30 16:56:29 -07:00
Leijurv
166eb97c3f make right click on arrival time out after 1 second 2019-04-30 16:52:27 -07:00
Leijurv
920ce745c2 fix some scuff from minebot 2019-04-29 23:08:17 -07:00
Leijurv
c931cde3ae fix error stacktrace on startup 2019-04-29 16:43:47 -07:00
Leijurv
f7a577e163 break from above 2019-04-29 16:02:44 -07:00
Leijurv
9bf3a041d4 might as well privatize 2019-04-29 14:59:25 -07:00
Leijurv
85eb7d8043 remember beyond render distance what is completed 2019-04-29 14:55:14 -07:00
Leijurv
b338dcc9de add path splice option 2019-04-29 11:46:21 -07:00
Leijurv
7d9b8ee4f3 that was too high tbh lol 2019-04-28 21:38:10 -07:00
Babbaj
0f61aaafb8 use ImmutableSet 2019-04-28 21:27:11 -04:00
Leijurv
0927e0e017 fix performance issues with explore 2019-04-27 16:16:36 -07:00
Leijurv
783a7cedc3 can combine distances 2019-04-27 16:03:58 -07:00
Leijurv
b1ee23ad50 taxicab only 2019-04-27 16:01:58 -07:00
Leijurv
9118e0b368 one byte savings means faster load times 2019-04-26 23:17:18 -07:00
Leijurv
5a0ccac0a1 maintain y while exploring 2019-04-25 13:40:33 -07:00
Leijurv
c8419dc362 i am rarted 2019-04-25 12:45:53 -07:00
Leijurv
9127ba2fce make explore a little less dummy 2019-04-25 12:18:25 -07:00
Leijurv
36858ca219 small cleanup 2019-04-25 11:22:11 -07:00
Leijurv
30469e2de2 pause mining for falling blocks, fixes #157 2019-04-25 11:10:18 -07:00
Leijurv
79c433b14d reduce suffocation from falling blocks above ore 2019-04-25 10:49:54 -07:00
Leijurv
bc419cfd1a fix loophole with falling blocks above ore 2019-04-24 22:10:41 -08:00
Leijurv
09fbf675ec fix build repeat 2019-04-23 17:42:13 -07:00
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
Brady
3d3a5f420e Fix unsafe creation of potentially invalid ResourceLocation 2019-04-16 20:15:51 -05: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
9c9c9d4387 fix region pruning 2019-04-14 10:06:37 -07:00
Leijurv
82d09a536d v1.3.1 2019-04-13 19:21:44 -07:00
Leijurv
6e49adea33 i WUV impact 2019-04-13 19:10:13 -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
f85afdbc70 Merge branch 'master' into 1.13.2 2019-04-12 21:57:01 -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
563028a5b3 fix invalid player move packet, and a bunch of things in world scanner 2019-04-09 19:30:48 -07:00
Leijurv
d5c317b88b Merge branch 'master' into 1.13.2 2019-04-09 18:17:53 -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
c59ec9da10 blank space 2019-03-23 22:17:40 -08:00
Leijurv
71491a7922 blank space 2019-03-23 22:17:40 -08:00
Leijurv
3a675836da Merge pull request #370 from babbaj/patch-1
use runAutoTest
2019-03-23 13:03:19 -07:00
babbaj
7e0fc81246 use runAutoTest 2019-03-23 15:55:16 -04:00
Leijurv
f970f932c7 great 2019-03-23 10:52:03 -07:00
Leijurv
52d2741f52 and lets try making it fail delibrately 2019-03-23 10:31:36 -07:00
Leijurv
7bc6765cac rart 2019-03-23 10:13:14 -07:00
Leijurv
85b2aea6e9 where is this writing??? 2019-03-23 09:52:49 -07:00
Leijurv
c6ba5481d9 one final attempt 2019-03-22 22:33:40 -07:00
Leijurv
81f47d5632 forgot file name lollll 2019-03-22 22:19:13 -07:00
Leijurv
9b1440ed2c that needs to be allowed 2019-03-22 22:07:12 -07:00
Leijurv
2a8dcee028 write to a file to indicate success 2019-03-22 22:05:27 -07:00
Leijurv
277ba3643c Merge branch 'master' into 1.13.2 2019-03-22 21:24:43 -07:00
Leijurv
170c2d35c2 perhaps updating debian will help 2019-03-22 21:17:20 -07:00
Leijurv
e5fbaf60f3 shutdownminecraftapplet 2019-03-22 21:04:35 -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
0deb854e1b v1.3.0 2019-03-21 16:40:18 -07:00
Leijurv
8268e3ec1b Merge branch 'master' into 1.13.2 2019-03-21 15:51:36 -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
af91da6a28 Merge branch 'master' into 1.13.2 2019-03-19 18:12:26 -07:00
Leijurv
9a15a65ad5 not needed anymore 2019-03-19 13:59:56 -07:00
Leijurv
0cbe9f81c8 Merge branch 'master' into 1.13.2 2019-03-15 16:58:23 -07:00
Leijurv
42afd2dd54 maybe proper exit code 2019-03-15 16:49:36 -07:00
Leijurv
315929f31c hey so what if we didnt do that 2019-03-15 16:39:59 -07:00
Leijurv
358aa80280 docker time 2019-03-15 16:22:51 -07:00
Leijurv
1dd9e11994 documentation resigned 2019-03-15 16:19:07 -07:00
Leijurv
5a8f02c944 unscuff everything 2019-03-15 16:11:14 -07:00
Leijurv
f248a5b677 make runClient work 2019-03-15 15:32:51 -07:00
Leijurv
e4a49c5529 fix launchtesting not found on runClient 2019-03-15 14:00:11 -07:00
Leijurv
449b44ba50 line 2019-03-14 16:32:14 -07:00
Leijurv
a00eec402e i love retina wtf 2019-03-14 16:32:04 -07:00
Leijurv
717779f742 air is stupid 2019-03-14 16:06:32 -07:00
Leijurv
6f843bd24d Merge branch 'master' into 1.13.2 2019-03-13 20:09:08 -07:00
Leijurv
d79fbea433 scuffed air 2019-03-13 18:08:15 -07:00
Leijurv
4d22c10ddb unscuff water, thanks wwe 2019-03-12 23:08:06 -07:00
Leijurv
1ea92a6092 😎 2019-03-12 22:49:23 -07:00
Leijurv
66eba84d06 consistent spacing 2019-03-12 18:54:36 -07:00
Leijurv
92e39b5d1d its over its done 2019-03-12 18:45:54 -07:00
Leijurv
0ddc47f473 i am rarted 2019-03-12 18:21:29 -07:00
Leijurv
ddfeca6947 unproject click cursed 2019-03-12 18:00:30 -07:00
Leijurv
6bd2e90cfd crash when pathing near shulker boxes 2019-03-12 17:18:58 -07:00
Leijurv
82505ddb01 online mode via env 2019-03-12 17:18:52 -07:00
Leijurv
2790d1d308 Merge branch 'master' into 1.13.2 2019-03-12 16:19:06 -07:00
Leijurv
11e503a022 many fixes 2019-03-12 16:17:43 -07:00
Leijurv
6fe49380ba pwned 2019-03-12 15:42:25 -07:00
Leijurv
1f2e267e3d fix a bunch of scuff 2019-03-12 15:41:58 -07:00
Leijurv
4cf6783622 fix the tests 2019-03-12 09:38:05 -07:00
Brady
82d77a7bac Update MixinGradle to 0.6.2
Includes fix ensuring that the SRGs are generated prior to Mixin annotation processing
2019-03-12 01:43:03 -05:00
Brady
841a927033 Merge remote-tracking branch 'origin/master' into 1.13.2 2019-03-12 01:09:11 -05:00
Brady
5a16561954 Working 1.13.2 development environment
Including a couple bugfixes to bad 1.13.2 code!!!
2019-03-12 01:05:39 -05:00
Brady
e2cc51908b Notch builds 2019-03-08 23:18:00 -06:00
Brady
1390e04435 Add versions in parenthesis for todos to fix stuff 2019-03-08 15:14:52 -06:00
Brady
84d961cbab Fix usages of Setting#get() 2019-03-08 15:12:55 -06:00
Brady
87b9d3915c Fix compiler errors
unproject needs to be resolved
2019-03-08 15:03:58 -06:00
Brady
c38d17563d Resolve merge conflicts
oh my god I should've updated my local branch before doing this
2019-03-08 14:44:49 -06:00
Brady
0c2af85ac0 Update to 1.13.2
Still need to setup method of launching, and Mixin support for ModLauncher
2019-03-08 14:30:43 -06:00
119 changed files with 3180 additions and 1442 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
* text=auto

1
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1 @@
<!-- No UwU's or OwO's allowed -->

1
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1 @@
<!-- No UwU's or OwO's allowed -->

4
.gitignore vendored
View File

@@ -11,6 +11,8 @@ build/
classes/
*.class
/out
# IntelliJ Files
.idea/
*.iml
@@ -18,4 +20,4 @@ classes/
# Copyright Files
!/.idea/copyright/Baritone.xml
!/.idea/copyright/profiles_settings.xml
!/.idea/copyright/profiles_settings.xml

View File

@@ -10,7 +10,7 @@ install:
script:
- docker run --rm cabaletta/baritone ./gradlew javadoc
- docker run --name baritone cabaletta/baritone /bin/sh -c "set -e; /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 128x128x24 -ac +extension GLX +render; DISPLAY=:99 BARITONE_AUTO_TEST=true ./gradlew runClient"
- docker run --name baritone cabaletta/baritone /bin/sh -c "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 128x128x24 -ac +extension GLX +render; DISPLAY=:99 BARITONE_AUTO_TEST=true ./gradlew runAutoTest; cat /code/autotest/success"
- docker cp baritone:/code/dist dist
- ls dist
- cat dist/checksums.txt

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,
threatening, offensive, or harmful.
Project maintainers have the right and responsibility to immediately remove
without any sort of dispute any issues or pull requests that do not align
with their corresponding templates. Absolutely no leniancy shall be accepted
with these terms.
## Scope
This Code of Conduct applies both within project spaces and in public spaces

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
RUN apt update -y
RUN apt install --target-release jessie-backports \
RUN apt install \
openjdk-8-jdk \
ca-certificates-java \
--assume-yes
RUN apt install -qq --force-yes mesa-utils libgl1-mesa-glx libxcursor1 libxrandr2 libxxf86vm1 x11-xserver-utils xfonts-base xserver-common
RUN apt install -qq --assume-yes mesa-utils libgl1-mesa-glx libxcursor1 libxrandr2 libxxf86vm1 x11-xserver-utils xfonts-base xserver-common
COPY . /code
@@ -21,4 +20,4 @@ WORKDIR /code
# source: https://github.com/tectonicus/tectonicus/issues/60#issuecomment-154239173
RUN dpkg -i scripts/xvfb_1.16.4-1_amd64.deb
RUN ./gradlew build
RUN ./gradlew build

View File

@@ -1,36 +1,40 @@
# Baritone
[![Build Status](https://travis-ci.com/cabaletta/baritone.svg?branch=master)](https://travis-ci.com/cabaletta/baritone)
[![Release](https://img.shields.io/github/release/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/releases)
[![Build Status](https://travis-ci.com/cabaletta/baritone.svg?branch=master)](https://travis-ci.com/cabaletta/baritone/)
[![Release](https://img.shields.io/github/release/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/releases/)
[![License](https://img.shields.io/badge/license-LGPL--3.0%20with%20anime%20exception-green.svg)](LICENSE)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/a73d037823b64a5faf597a18d71e3400)](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=cabaletta/baritone&amp;utm_campaign=Badge_Grade)
[![HitCount](http://hits.dwyl.com/cabaletta/baritone.svg)](http://hits.dwyl.com/cabaletta/baritone)
[![HitCount](http://hits.dwyl.com/cabaletta/baritone.svg)](http://hits.dwyl.com/cabaletta/baritone/)
[![GitHub All Releases](https://img.shields.io/github/downloads/cabaletta/baritone/total.svg)](https://github.com/cabaletta/baritone/releases/)
[![Minecraft](https://img.shields.io/badge/MC-1.12.2-green.svg)](https://github.com/cabaletta/baritone/tree/master/)
[![Minecraft](https://img.shields.io/badge/MC-1.13.2-brightgreen.svg)](https://github.com/cabaletta/baritone/tree/1.13.2/)
[![Code of Conduct](https://img.shields.io/badge/%E2%9D%A4-code%20of%20conduct-blue.svg?style=flat)](https://github.com/cabaletta/baritone/blob/master/CODE_OF_CONDUCT.md)
[![Known Vulnerabilities](https://snyk.io/test/github/cabaletta/baritone/badge.svg?targetFile=build.gradle)](https://snyk.io/test/github/cabaletta/baritone?targetFile=build.gradle)
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/cabaletta/baritone/issues)
[![Contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/cabaletta/baritone/issues/)
[![Issues](https://img.shields.io/github/issues/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/issues/)
[![GitHub issues-closed](https://img.shields.io/github/issues-closed/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/issues?q=is%3Aissue+is%3Aclosed)
[![Pull Requests](https://img.shields.io/github/issues-pr/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/pulls/)
![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)
![](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)
![Lines of Code](https://tokei.rs/b1/github/cabaletta/baritone?category=code)
[![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/)
[![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.6%20/%20v1.3.2-brightgreen.svg)](https://impactdevelopment.github.io/)
[![ForgeHax integration](https://img.shields.io/badge/ForgeHax%20%22integration%22-scuffed-yellow.svg)](https://github.com/fr1kin/ForgeHax/)
[![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/)
[![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)
[![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.
Baritone is the pathfinding system used in [Impact](https://impactdevelopment.github.io/) since 4.4. There's a [showcase video](https://www.youtube.com/watch?v=yI8hgW_m6dQ) made by @Adovin#3153 on Baritone's integration into Impact. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a video I made showing off what it can do.
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 easiest way to install Baritone is to install [Impact](https://impactdevelopment.github.io/), which comes with Baritone. The second easiest way (for 1.12.2 only) is to install the forge jar from [releases](https://github.com/cabaletta/baritone/releases). Otherwise, see [Installation & setup](SETUP.md). Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it.
Have committed at least once a day for the last 7 months =D 🦀
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 and 1.13.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 11 months =D 🦀
1Leijurv3DWTrGAfmmiTphjhXLvQiHg7K2
@@ -46,7 +50,7 @@ Here are some links to help to get started:
- [Settings](https://baritone.leijurv.com/baritone/api/Settings.html#field.detail)
- [Baritone chat control usage](USAGE.md)
- [Usage (chat control)](USAGE.md)
# API
@@ -67,11 +71,11 @@ BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAnd
## Can I use Baritone as a library in my custom utility client?
That's what it's for, sure! (As long as usage is in compliance with the LGPL 3 License)
That's what it's for, sure! (As long as usage is in compliance with the LGPL 3.0 License)
## How is it so fast?
Magic. (Hours of [leijurv](https://github.com/leijurv) enduring excruciating pain)
Magic. (Hours of [leijurv](https://github.com/leijurv/) enduring excruciating pain)
## Why is it called Baritone?

View File

@@ -1,7 +1,11 @@
# Installation
The easiest way to install Baritone is to install [Impact](https://impactdevelopment.github.io/), which comes with Baritone.
Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it.
## 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)

View File

@@ -2,30 +2,20 @@
# Prefix
Baritone commands can by default be typed in the chatbox. However if you make a typo, like typing "gola 10000 10000" instead of goal it goes into public chat, which is bad.
Therefore you can use a prefix before your messages.
On Baritone v1.1.0 and newer: The prefix is `#` by default. Anything beginning with `#` isn't sent, and is only interpreted by Baritone.
For older than v1.1.0, `#` must be enabled by toggling on the `prefix` setting.
**Only** in Impact is `.b` also a valid prefix. In 4.4, `#` does **not** work, neither does saying the commands directly in chat. `#` works by default in 4.5 (not 4.4).
Other clients like Kami and Asuna have their own custom things (like `-path`), and can disable direct chat control entirely.
Baritone's chat control prefix is `#` by default. In Impact, you can also use `.b` as a prefix. (for example, `.b click` instead of `#click`)
Baritone commands can also by default be typed in the chatbox. However if you make a typo, like typing "gola 10000 10000" instead of "goal" it goes into public chat, which is bad, so using `#` is suggested.
To disable direct chat control (with no prefix), turn off the `chatControl` setting. To disable chat control with the `#` prefix, turn off the `prefixControl` setting. In Impact, `.b` cannot be disabled. Be careful that you don't leave yourself with all control methods disabled (if you do, reset your settings by deleting the file `minecraft/baritone/settings.txt` and relaunching).
# Commands
**All** of these commands may need a prefix before them, as above ^.
`help` for (rudimentary) help. You can see what it says [here](https://github.com/cabaletta/baritone/blob/master/src/main/java/baritone/utils/ExampleBaritoneControl.java#L53).
`help` for (rudimentary) help. You can see what it says [here](https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/utils/ExampleBaritoneControl.java#L47).
To toggle a boolean setting, just say its name in chat (for example saying `allowBreak` toggles whether Baritone will consider breaking blocks). For a numeric setting, say its name then the new value (like `primaryTimeoutMS 250`). It's case insensitive. To reset a setting to its default value, say `acceptableThrowawayItems reset`. To reset all settings, say `reset`. To see all settings that have been modified from their default values, say `modified`.
Some common examples:
- `thisway 1000` then `path` to go in the direction you're facing for a thousand blocks
- `goal x y z` or `goal x z` or `goal y`, then `path` to go to a certain coordinate
@@ -34,16 +24,20 @@ Some common examples:
- `cancel` or `stop` to stop everything
- `goto portal` or `goto ender_chest` or `goto block_type` to go to a block. (in Impact, `.goto` is an alias for `.b goto` for the most part)
- `mine diamond_ore` to mine diamond ore (turn on the setting `legitMine` to only mine ores that it can actually see. It will explore randomly around y=11 until it finds them.)
- `click` to click your destination on the screen. left click to path into it, right click to path on top of it.
- `click` to click your destination on the screen. Right click path to on top of the block, left click to path into it (either at foot level or eye level), and left click and drag to clear all blocks from an area.
- `follow playerName` to follow a player. `follow` to follow the entity you're looking at (only works if it hitting range). `followplayers` to follow any players in range (combine with Kill Aura for a fun time).
- `save waypointName` to save a waypoint. `goto waypointName` to go to it.
- `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).
- `tunnel` to dig just straight ahead and make a tunnel
- `farm` to automatically harvest, replant, or bone meal crops
- `axis` to go to an axis or diagonal axis at y=120 (`axisHeight` is a configurable setting, defaults to 120).
- `explore x z` to explore the world from the origin of x,z. Leave out x and z to default to player feet. This will continually path towards the closest chunk to the origin that it's never seen before. `explorefilter filter.json` with optional invert can be used to load in a list of chunks to load.
- `invert` to invert the current goal and path. This gets as far away from it as possible, instead of as close as possible. For example, do `goal` then `invert` to run as far as possible from where you're standing at the start.
- `render` to rerender the world in case `renderCachedChunks` is being glitchy
- `version` to get the version of Baritone you're running
- `damn` daniel
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/api/java/baritone/api/utils/ExampleBaritoneControl.java).
All the settings and documentation are <a href="https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/Settings.java">here</a>. If you find HTML easier to read than Javadoc, you can look <a href="https://baritone.leijurv.com/baritone/api/Settings.html#field.detail">here</a>.
@@ -53,18 +47,23 @@ There are about a hundred settings, but here are some fun / interesting / import
- `allowPlace`
- `allowParkour`
- `allowParkourPlace`
- `blockPlacementPenalty`
- `renderCachedChunks` (and `cachedChunksOpacity`) <-- very fun but you need a beefy computer
- `avoidance`
- `avoidance` (avoidance of mobs / mob spawners)
- `legitMine`
- `followRadius`
- `backfill` (fill in tunnels behind you)
- `buildInLayers`
- `buildRepeatDistance` and `buildRepeatDirection`
- `worldExploringChunkOffset`
- `acceptableThrowawayItems`
- `blocksToAvoidBreaking`
# Troubleshooting / common issues
## Baritone highlights a block in green but gets completely stuck? Also I'm using Baritone with Future?
Baritone is trying to right click to place a block there, but it can't since there's a conflicting mixin. Baritone can't force click right click when Future is also installed. Left click **does work** on recent Baritone even with Future, however. For now, turn off `allowPlace` and Baritone will only search for paths that don't require placing blocks to complete. `allowBreak` can remain on.
## Why doesn't Baritone respond to any of my chat commands?
This could be one of many things.

View File

@@ -16,33 +16,33 @@
*/
group 'baritone'
version '1.2.5'
version '1.3.3'
buildscript {
repositories {
jcenter()
maven {
name = 'forge'
url = 'http://files.minecraftforge.net/maven'
}
maven {
name = 'SpongePowered'
url = 'http://repo.spongepowered.org/maven'
name = 'impactdevelopment-repo'
url = 'https://impactdevelopment.github.io/maven/'
}
jcenter()
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
classpath 'org.spongepowered:mixingradle:0.6-SNAPSHOT'
classpath group: 'com.github.ImpactDevelopment', name: 'ForgeGradle', version: '3.0.115'
classpath group: 'com.github.ImpactDevelopment', name: 'MixinGradle', version: '0.6.2'
}
}
import baritone.gradle.task.CreateDistTask
import baritone.gradle.task.ProguardTask
import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: 'java'
apply plugin: 'net.minecraftforge.gradle.tweaker-client'
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'org.spongepowered.mixin'
sourceCompatibility = targetCompatibility = '1.8'
@@ -52,19 +52,67 @@ compileJava {
}
sourceSets {
api {
compileClasspath += main.compileClasspath
}
main {
compileClasspath += api.output
}
test {
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
runtimeClasspath += main.compileClasspath + main.runtimeClasspath + main.output
}
launch {
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
runtimeClasspath += main.compileClasspath + main.runtimeClasspath + main.output
}
}
minecraft {
version = '1.12.2'
mappings = 'stable_39'
tweakClass = 'baritone.launch.BaritoneTweaker'
runDir = 'run'
task sourceJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.api.allSource
}
// The sources jar should use SRG names not MCP to ensure compatibility with all mappings
makeObfSourceJar = true
minecraft {
mappings channel: 'snapshot', version: '20190307-1.13.1'
reobfMappings 'notch'
runs {
client {
workingDirectory project.file('run')
source sourceSets.launch
main 'baritone.launch.LaunchTesting'
environment 'assetIndex', '{asset_index}'
environment 'assetDirectory', downloadAssets.output
environment 'nativesDirectory', extractNatives.output
environment 'tweakClass', 'baritone.launch.BaritoneTweaker'
if (Os.isFamily(Os.FAMILY_MAC)) {
jvmArgs "-XstartOnFirstThread"
}
}
autoTest {
workingDirectory project.file('autotest')
source sourceSets.launch
main 'baritone.launch.LaunchTesting'
environment 'assetIndex', '{asset_index}'
environment 'assetDirectory', downloadAssets.output
environment 'nativesDirectory', extractNatives.output
environment 'tweakClass', 'baritone.launch.BaritoneTweaker'
environment 'BARITONE_AUTO_TEST', 'true'
if (Os.isFamily(Os.FAMILY_MAC)) {
jvmArgs "-XstartOnFirstThread"
}
}
}
}
repositories {
@@ -82,6 +130,12 @@ repositories {
}
dependencies {
minecraft 'com.github.ImpactDevelopment:Vanilla:1.13.2'
runtime launchCompile('net.minecraft:launchwrapper:1.12') {
exclude module: 'lwjgl'
}
runtime launchCompile('org.ow2.asm:asm-debug-all:5.2')
runtime launchCompile('com.github.ImpactDevelopment:SimpleTweaker:1.2')
runtime launchCompile('org.spongepowered:mixin:0.7.11-SNAPSHOT') {
// Mixin includes a lot of dependencies that are too up-to-date
@@ -91,6 +145,7 @@ dependencies {
exclude module: 'commons-io'
exclude module: 'log4j-core'
}
testImplementation 'junit:junit:4.12'
}

View File

@@ -40,17 +40,13 @@ class BaritoneGradleTask extends DefaultTask {
PROGUARD_STANDALONE_CONFIG = "standalone.pro",
PROGUARD_EXPORT_PATH = "proguard_out.jar",
TEMP_LIBRARY_DIR = "tempLibraries/",
ARTIFACT_STANDARD = "%s-%s.jar",
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
ARTIFACT_API = "%s-api-%s.jar",
ARTIFACT_STANDALONE = "%s-standalone-%s.jar",
ARTIFACT_FORGE_API = "%s-api-forge-%s.jar",
ARTIFACT_FORGE_STANDALONE = "%s-standalone-forge-%s.jar";
ARTIFACT_STANDALONE = "%s-standalone-%s.jar";
protected String artifactName, artifactVersion;
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, artifactForgeApiPath, artifactForgeStandalonePath, proguardOut;
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, proguardOut;
protected void verifyArtifacts() throws IllegalStateException {
this.artifactName = getProject().getName();
@@ -60,8 +56,6 @@ class BaritoneGradleTask extends DefaultTask {
this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED));
this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API));
this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE));
this.artifactForgeApiPath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_API));
this.artifactForgeStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_STANDALONE));
this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH);

View File

@@ -45,8 +45,6 @@ public class CreateDistTask extends BaritoneGradleTask {
Path api = getRelativeFile("dist/" + formatVersion(ARTIFACT_API));
Path standalone = getRelativeFile("dist/" + formatVersion(ARTIFACT_STANDALONE));
Path unoptimized = getRelativeFile("dist/" + formatVersion(ARTIFACT_UNOPTIMIZED));
Path forgeApi = getRelativeFile("dist/" + formatVersion(ARTIFACT_FORGE_API));
Path forgeStandalone = getRelativeFile("dist/" + formatVersion(ARTIFACT_FORGE_STANDALONE));
// NIO will not automatically create directories
Path dir = getRelativeFile("dist/");
@@ -58,11 +56,9 @@ public class CreateDistTask extends BaritoneGradleTask {
Files.copy(this.artifactApiPath, api, REPLACE_EXISTING);
Files.copy(this.artifactStandalonePath, standalone, REPLACE_EXISTING);
Files.copy(this.artifactUnoptimizedPath, unoptimized, REPLACE_EXISTING);
Files.copy(this.artifactForgeApiPath, forgeApi, REPLACE_EXISTING);
Files.copy(this.artifactForgeStandalonePath, forgeStandalone, REPLACE_EXISTING);
// Calculate all checksums and format them like "shasum"
List<String> shasum = Stream.of(api, forgeApi, standalone, forgeStandalone, unoptimized)
List<String> shasum = Stream.of(api, standalone, unoptimized)
.map(path -> sha1(path) + " " + path.getFileName().toString())
.collect(Collectors.toList());

View File

@@ -18,26 +18,18 @@
package baritone.gradle.task;
import baritone.gradle.util.Determinizer;
import baritone.gradle.util.MappingType;
import baritone.gradle.util.ReobfWrapper;
import org.apache.commons.io.IOUtils;
import org.gradle.api.NamedDomainObjectContainer;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.internal.plugins.DefaultConvention;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.TaskAction;
import org.gradle.internal.Pair;
import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -49,18 +41,12 @@ import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
*/
public class ProguardTask extends BaritoneGradleTask {
private static final Pattern TEMP_LIBRARY_PATTERN = Pattern.compile("-libraryjars 'tempLibraries\\/([a-zA-Z0-9/_\\-\\.]+)\\.jar'");
@Input
private String url;
@Input
private String extract;
private List<String> requiredLibraries;
private File mixin;
@TaskAction
protected void exec() throws Exception {
super.verifyArtifacts();
@@ -70,7 +56,6 @@ public class ProguardTask extends BaritoneGradleTask {
downloadProguard();
extractProguard();
generateConfigs();
acquireDependencies();
proguardApi();
proguardStandalone();
cleanup();
@@ -81,7 +66,7 @@ public class ProguardTask extends BaritoneGradleTask {
Files.delete(this.artifactUnoptimizedPath);
}
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString(), Optional.empty());
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString());
}
private void downloadProguard() throws Exception {
@@ -114,6 +99,19 @@ public class ProguardTask extends BaritoneGradleTask {
String out = IOUtils.toString(p.getInputStream(), "UTF-8").split("\n")[0].split("Opened ")[1].replace("]", "");
template.add(2, "-libraryjars '" + out + "'");
// Discover all of the libraries that we will need to acquire from gradle
acquireDependencies().forEach(f -> {
if (f.toString().endsWith("-recomp.jar")) {
// remove MCP mapped jar
return;
}
if (f.toString().endsWith("client-extra.jar")) {
// go from the extra to the original downloaded client
f = new File(f.getParentFile(), "client.jar");
}
template.add(2, "-libraryjars '" + f + "'");
});
// API config doesn't require any changes from the changes that we made to the template
Files.write(getTemporaryFile(PROGUARD_API_CONFIG), template);
@@ -121,165 +119,20 @@ public class ProguardTask extends BaritoneGradleTask {
List<String> standalone = new ArrayList<>(template);
standalone.removeIf(s -> s.contains("# this is the keep api"));
Files.write(getTemporaryFile(PROGUARD_STANDALONE_CONFIG), standalone);
// Discover all of the libraries that we will need to acquire from gradle
this.requiredLibraries = new ArrayList<>();
template.forEach(line -> {
if (!line.startsWith("#")) {
Matcher m = TEMP_LIBRARY_PATTERN.matcher(line);
if (m.find()) {
this.requiredLibraries.add(m.group(1));
}
}
});
}
private void acquireDependencies() throws Exception {
// Create a map of all of the dependencies that we are able to access in this project
// Likely a better way to do this, I just pair the dependency with the first valid configuration
Map<String, Pair<Configuration, Dependency>> dependencyLookupMap = new HashMap<>();
getProject().getConfigurations().stream().filter(Configuration::isCanBeResolved).forEach(config ->
config.getAllDependencies().forEach(dependency ->
dependencyLookupMap.putIfAbsent(dependency.getName() + "-" + dependency.getVersion(), Pair.of(config, dependency))));
// Create the directory if it doesn't already exist
Path tempLibraries = getTemporaryFile(TEMP_LIBRARY_DIR);
if (!Files.exists(tempLibraries)) {
Files.createDirectory(tempLibraries);
}
// Iterate the required libraries to copy them to tempLibraries
for (String lib : this.requiredLibraries) {
// copy from the forgegradle cache
if (lib.equals("minecraft")) {
Path cachedJar = getMinecraftJar();
Path inTempDir = getTemporaryFile("tempLibraries/minecraft.jar");
// TODO: maybe try not to copy every time
Files.copy(cachedJar, inTempDir, REPLACE_EXISTING);
continue;
}
// Find a configuration/dependency pair that matches the desired library
Pair<Configuration, Dependency> pair = null;
for (Map.Entry<String, Pair<Configuration, Dependency>> entry : dependencyLookupMap.entrySet()) {
if (entry.getKey().startsWith(lib)) {
pair = entry.getValue();
}
}
// The pair must be non-null
Objects.requireNonNull(pair);
// Find the library jar file, and copy it to tempLibraries
for (File file : pair.getLeft().files(pair.getRight())) {
if (file.getName().startsWith(lib)) {
if (lib.contains("mixin")) {
mixin = file;
}
Files.copy(file.toPath(), getTemporaryFile("tempLibraries/" + lib + ".jar"), REPLACE_EXISTING);
}
}
}
if (mixin == null) {
throw new IllegalStateException("Unable to find mixin jar");
}
}
// a bunch of epic stuff to get the path to the cached jar
private Path getMinecraftJar() throws Exception {
MappingType mappingType;
try {
mappingType = getMappingType();
} catch (Exception e) {
System.err.println("Failed to get mapping type, assuming NOTCH.");
mappingType = MappingType.NOTCH;
}
String suffix;
switch (mappingType) {
case NOTCH:
suffix = "";
break;
case SEARGE:
suffix = "-srgBin";
break;
case CUSTOM:
throw new IllegalStateException("Custom mappings not supported!");
default:
throw new IllegalStateException("Unknown mapping type: " + mappingType);
}
DefaultConvention convention = (DefaultConvention) this.getProject().getConvention();
Object extension = convention.getAsMap().get("minecraft");
Objects.requireNonNull(extension);
// for some reason cant use Class.forName
Class<?> class_baseExtension = extension.getClass().getSuperclass().getSuperclass().getSuperclass(); // <-- cursed
Field f_replacer = class_baseExtension.getDeclaredField("replacer");
f_replacer.setAccessible(true);
Object replacer = f_replacer.get(extension);
Class<?> class_replacementProvider = replacer.getClass();
Field replacement_replaceMap = class_replacementProvider.getDeclaredField("replaceMap");
replacement_replaceMap.setAccessible(true);
Map<String, Object> replacements = (Map) replacement_replaceMap.get(replacer);
String cacheDir = replacements.get("CACHE_DIR").toString() + "/net/minecraft";
String mcVersion = replacements.get("MC_VERSION").toString();
String mcpInsert = replacements.get("MAPPING_CHANNEL").toString() + "/" + replacements.get("MAPPING_VERSION").toString();
String fullJarName = "minecraft-" + mcVersion + suffix + ".jar";
String baseDir = String.format("%s/minecraft/%s/", cacheDir, mcVersion);
String jarPath;
if (mappingType == MappingType.SEARGE) {
jarPath = String.format("%s/%s/%s", baseDir, mcpInsert, fullJarName);
} else {
jarPath = baseDir + fullJarName;
}
jarPath = jarPath
.replace("/", File.separator)
.replace("\\", File.separator); // hecking regex
return new File(jarPath).toPath();
}
// throws IllegalStateException if mapping type is ambiguous or it fails to find it
private MappingType getMappingType() {
// if it fails to find this then its probably a forgegradle version problem
Set<Object> reobf = (NamedDomainObjectContainer<Object>) this.getProject().getExtensions().getByName("reobf");
List<MappingType> mappingTypes = getUsedMappingTypes(reobf);
long mappingTypesUsed = mappingTypes.size();
if (mappingTypesUsed == 0) {
throw new IllegalStateException("Failed to find mapping type (no jar task?)");
}
if (mappingTypesUsed > 1) {
throw new IllegalStateException("Ambiguous mapping type (multiple jars with different mapping types?)");
}
return mappingTypes.get(0);
}
private List<MappingType> getUsedMappingTypes(Set<Object> reobf) {
return reobf.stream()
.map(ReobfWrapper::new)
.map(ReobfWrapper::getMappingType)
.distinct()
.collect(Collectors.toList());
private Stream<File> acquireDependencies() {
return getProject().getConvention().getPlugin(JavaPluginConvention.class).getSourceSets().findByName("launch").getRuntimeClasspath().getFiles().stream().filter(File::isFile);
}
private void proguardApi() throws Exception {
runProguard(getTemporaryFile(PROGUARD_API_CONFIG));
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString(), Optional.empty());
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeApiPath.toString(), Optional.of(mixin));
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString());
}
private void proguardStandalone() throws Exception {
runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG));
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString(), Optional.empty());
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeStandalonePath.toString(), Optional.of(mixin));
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString());
}
private void cleanup() {

View File

@@ -22,7 +22,10 @@ import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.*;
import java.util.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
@@ -36,7 +39,7 @@ import java.util.stream.Collectors;
*/
public class Determinizer {
public static void determinize(String inputPath, String outputPath, Optional<File> toInclude) throws IOException {
public static void determinize(String inputPath, String outputPath) throws IOException {
System.out.println("Running Determinizer");
System.out.println(" Input path: " + inputPath);
System.out.println(" Output path: " + outputPath);
@@ -63,30 +66,10 @@ public class Determinizer {
if (entry.getName().endsWith(".refmap.json")) {
JsonObject object = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry))).getAsJsonObject();
jos.write(writeSorted(object).getBytes());
} else if (entry.getName().equals("META-INF/MANIFEST.MF") && toInclude.isPresent()) { // only replace for forge jar
ByteArrayOutputStream cancer = new ByteArrayOutputStream();
copy(jarFile.getInputStream(entry), cancer);
String manifest = new String(cancer.toByteArray());
if (!manifest.contains("baritone.launch.BaritoneTweaker")) {
throw new IllegalStateException("unable to replace");
}
manifest = manifest.replace("baritone.launch.BaritoneTweaker", "org.spongepowered.asm.launch.MixinTweaker");
jos.write(manifest.getBytes());
} else {
copy(jarFile.getInputStream(entry), jos);
}
}
if (toInclude.isPresent()) {
try (JarFile mixin = new JarFile(toInclude.get())) {
for (JarEntry entry : mixin.stream().sorted(Comparator.comparing(JarEntry::getName)).collect(Collectors.toList())) {
if (entry.getName().startsWith("META-INF") && !entry.getName().startsWith("META-INF/services")) {
continue;
}
jos.putNextEntry(entry);
copy(mixin.getInputStream(entry), jos);
}
}
}
jos.finish();
}
}

View File

@@ -1,63 +0,0 @@
/*
* 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.gradle.util;
import java.lang.reflect.Field;
import java.util.Objects;
/**
* All credits go to AsmLibGradle and its contributors.
*
* @see <a href="https://github.com/pozzed/AsmLibGradle/blob/8f917dbc3939eab7a3d9daf54d9d285fdf34f4b2/src/main/java/net/futureclient/asmlib/forgegradle/ReobfWrapper.java">Original Source</a>
*/
public class ReobfWrapper {
private final Object instance;
private final Class<?> type;
public ReobfWrapper(Object instance) {
this.instance = instance;
Objects.requireNonNull(instance);
this.type = instance.getClass();
}
public String getName() {
try {
Field nameField = type.getDeclaredField("name");
nameField.setAccessible(true);
return (String) nameField.get(this.instance);
} catch (ReflectiveOperationException ex) {
throw new IllegalStateException(ex);
}
}
public MappingType getMappingType() {
try {
Field enumField = type.getDeclaredField("mappingType");
enumField.setAccessible(true);
Enum<?> aEnum = (Enum<?>) enumField.get(this.instance);
MappingType mappingType = MappingType.values()[aEnum.ordinal()];
if (!aEnum.name().equals(mappingType.name())) {
throw new IllegalStateException("ForgeGradle ReobfMappingType is not equivalent to MappingType (version error?)");
}
return mappingType;
} catch (ReflectiveOperationException ex) {
throw new IllegalStateException(ex);
}
}
}

54
scripts/proguard.pro vendored
View File

@@ -14,6 +14,8 @@
# lwjgl is weird
-dontwarn org.lwjgl.**
# also lwjgl lol
-dontwarn module-info
-keep class baritone.api.** { *; } # this is the keep api
@@ -21,6 +23,8 @@
-keep class baritone.BaritoneProvider
-keep class baritone.api.IBaritoneProvider
-keep class baritone.api.utils.MyChunkPos { *; } # even in standalone we need to keep this for gson reflect
# setting names are reflected from field names, so keep field names
-keepclassmembers class baritone.api.Settings {
public <fields>;
@@ -29,56 +33,6 @@
# need to keep mixin names
-keep class baritone.launch.** { *; }
# copy all necessary libraries into tempLibraries to build
# The correct jar will be copied from the forgegradle cache based on the mapping type being compiled with
-libraryjars 'tempLibraries/minecraft.jar'
-libraryjars 'tempLibraries/SimpleTweaker-1.2.jar'
-libraryjars 'tempLibraries/authlib-1.5.25.jar'
-libraryjars 'tempLibraries/codecjorbis-20101023.jar'
-libraryjars 'tempLibraries/codecwav-20101023.jar'
-libraryjars 'tempLibraries/commons-codec-1.10.jar'
-libraryjars 'tempLibraries/commons-compress-1.8.1.jar'
-libraryjars 'tempLibraries/commons-io-2.5.jar'
-libraryjars 'tempLibraries/commons-lang3-3.5.jar'
-libraryjars 'tempLibraries/commons-logging-1.1.3.jar'
-libraryjars 'tempLibraries/fastutil-7.1.0.jar'
-libraryjars 'tempLibraries/gson-2.8.0.jar'
-libraryjars 'tempLibraries/guava-21.0.jar'
-libraryjars 'tempLibraries/httpclient-4.3.3.jar'
-libraryjars 'tempLibraries/httpcore-4.3.2.jar'
-libraryjars 'tempLibraries/icu4j-core-mojang-51.2.jar'
-libraryjars 'tempLibraries/jinput-2.0.5.jar'
-libraryjars 'tempLibraries/jna-4.4.0.jar'
-libraryjars 'tempLibraries/jopt-simple-5.0.3.jar'
-libraryjars 'tempLibraries/jsr305-3.0.1.jar'
-libraryjars 'tempLibraries/jutils-1.0.0.jar'
-libraryjars 'tempLibraries/libraryjavasound-20101123.jar'
-libraryjars 'tempLibraries/librarylwjglopenal-20100824.jar'
-libraryjars 'tempLibraries/log4j-api-2.8.1.jar'
-libraryjars 'tempLibraries/log4j-core-2.8.1.jar'
# startsWith is used to check the library, and mac/linux differ in which version they use
# this is FINE
-libraryjars 'tempLibraries/lwjgl-.jar'
-libraryjars 'tempLibraries/lwjgl_util-.jar'
-libraryjars 'tempLibraries/netty-all-4.1.9.Final.jar'
-libraryjars 'tempLibraries/oshi-core-1.1.jar'
-libraryjars 'tempLibraries/patchy-1.1.jar'
-libraryjars 'tempLibraries/platform-3.4.0.jar'
-libraryjars 'tempLibraries/realms-1.10.22.jar'
-libraryjars 'tempLibraries/soundsystem-20120107.jar'
-libraryjars 'tempLibraries/text2speech-1.10.3.jar'
-libraryjars 'tempLibraries/mixin-0.7.11-SNAPSHOT.jar'
-libraryjars 'tempLibraries/launchwrapper-1.11.jar' # TODO why does only 1.11.jar exist?
# Keep - Applications. Keep all application classes, along with their 'main'
# methods.
-keepclasseswithmembers public class * {

View File

@@ -71,6 +71,18 @@ public interface IBaritone {
*/
IBuilderProcess getBuilderProcess();
/**
* @return The {@link IExploreProcess} instance
* @see IExploreProcess
*/
IExploreProcess getExploreProcess();
/**
* @return The {@link IFarmProcess} instance
* @see IFarmProcess
*/
IFarmProcess getFarmProcess();
/**
* @return The {@link ICustomGoalProcess} instance
* @see ICustomGoalProcess
@@ -115,4 +127,6 @@ public interface IBaritone {
* @see IEventBus
*/
IEventBus getGameEventHandler();
void openClick();
}

View File

@@ -18,13 +18,18 @@
package baritone.api;
import baritone.api.utils.SettingsUtil;
import baritone.api.utils.TypeUtils;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.util.math.Vec3i;
import net.minecraft.util.text.ITextComponent;
import java.awt.*;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
import java.util.List;
import java.util.function.Consumer;
@@ -58,7 +63,9 @@ public final class Settings {
/**
* It doesn't actually take twenty ticks to place a block, this cost is so high
* because we want to generally conserve blocks which might be limited
* because we want to generally conserve blocks which might be limited.
* <p>
* Decrease to make Baritone more often consider paths that would require placing blocks
*/
public final Setting<Double> blockPlacementPenalty = new Setting<>(20D);
@@ -77,7 +84,7 @@ public final class Settings {
/**
* Walking on water uses up hunger really quick, so penalize it
*/
public final Setting<Double> walkOnWaterOnePenalty = new Setting<>(5D);
public final Setting<Double> walkOnWaterOnePenalty = new Setting<>(3D);
/**
* Allow Baritone to fall arbitrary distances and place a water bucket beneath it.
@@ -91,6 +98,11 @@ public final class Settings {
*/
public final Setting<Boolean> assumeWalkOnWater = new Setting<>(false);
/**
* If you have Fire Resistance and Jesus then I guess you could turn this on lol
*/
public final Setting<Boolean> assumeWalkOnLava = new Setting<>(false);
/**
* Assume step functionality; don't jump on an Ascend.
*/
@@ -108,7 +120,7 @@ public final class Settings {
/**
* If true, parkour is allowed to make jumps when standing on blocks at the maximum height, so player feet is y=256
* <p>
* Defaults to false because this fails on constantiam
* Defaults to false because this fails on constantiam. Please let me know if this is ever disabled. Please.
*/
public final Setting<Boolean> allowJumpAt256 = new Setting<>(false);
@@ -121,15 +133,47 @@ public final class Settings {
*/
public final Setting<Boolean> allowDiagonalDescend = new Setting<>(false);
/**
* Allow mining the block directly beneath its feet
* <p>
* Turn this off to force it to make more staircases and less shafts
*/
public final Setting<Boolean> allowDownward = new Setting<>(true);
/**
* Blocks that Baritone is allowed to place (as throwaway, for sneak bridging, pillaring, etc.)
*/
public final Setting<List<Item>> acceptableThrowawayItems = new Setting<>(new ArrayList<>(Arrays.asList(
Item.getItemFromBlock(Blocks.DIRT),
Item.getItemFromBlock(Blocks.COBBLESTONE),
Item.getItemFromBlock(Blocks.NETHERRACK)
Blocks.DIRT.asItem(),
Blocks.COBBLESTONE.asItem(),
Blocks.NETHERRACK.asItem(),
Blocks.STONE.asItem()
)));
/**
* 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<>(Arrays.asList( // TODO can this be a HashSet or ImmutableSet?
Blocks.CRAFTING_TABLE,
Blocks.FURNACE,
Blocks.CHEST,
Blocks.TRAPPED_CHEST
)));
/**
* If this setting is true, Baritone will never break a block that is adjacent to an unsupported falling block.
* <p>
* I.E. it will never trigger cascading sand / gravel falls
*/
public final Setting<Boolean> avoidUpdatingFallingBlocks = new Setting<>(true);
/**
* 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.
@@ -170,11 +214,28 @@ public final class Settings {
*/
public final Setting<Boolean> sprintAscends = new Setting<>(true);
/**
* If we overshoot a traverse and end up one block beyond the destination, mark it as successful anyway.
* <p>
* This helps with speed at >=20m/s
*/
public final Setting<Boolean> overshootTraverse = new Setting<>(true);
/**
* When breaking blocks for a movement, wait until all falling blocks have settled before continuing
*/
public final Setting<Boolean> pauseMiningForFallingBlocks = new Setting<>(true);
/**
* How many ticks between right clicks are allowed. Default in game is 4
*/
public final Setting<Integer> rightClickSpeed = new Setting<>(4);
/**
* How many degrees to randomize the yaw every tick. Set to 0 to disable
*/
public final Setting<Double> randomLooking = new Setting<>(2d);
/**
* This is the big A* setting.
* As long as your cost heuristic is an *underestimate*, it's guaranteed to find you the best path.
@@ -386,10 +447,12 @@ public final class Settings {
* On save, delete from RAM any cached regions that are more than 1024 blocks away from the player
* <p>
* Temporarily disabled
* <p>
* Temporarily reenabled
*
* @see <a href="https://github.com/cabaletta/baritone/issues/248">Issue #248</a>
*/
public final Setting<Boolean> pruneRegionsFromRAM = new Setting<>(false);
public final Setting<Boolean> pruneRegionsFromRAM = new Setting<>(true);
/**
* Remember the contents of containers (chests, echests, furnaces)
@@ -398,6 +461,11 @@ public final class Settings {
*/
public final Setting<Boolean> containerMemory = new Setting<>(false);
/**
* Fill in blocks behind you
*/
public final Setting<Boolean> backfill = new Setting<>(false);
/**
* Print all the debug messages to chat
*/
@@ -424,6 +492,11 @@ public final class Settings {
*/
public final Setting<Boolean> renderGoal = new Setting<>(true);
/**
* Render selection boxes
*/
public final Setting<Boolean> renderSelectionBoxes = new Setting<>(true);
/**
* Ignore depth when rendering the goal
*/
@@ -476,6 +549,8 @@ public final class Settings {
/**
* Exclusively use cached chunks for pathing
* <p>
* Never turn this on
*/
public final Setting<Boolean> pathThroughCachedOnly = new Setting<>(false);
@@ -506,7 +581,7 @@ public final class Settings {
public final Setting<Boolean> renderCachedChunks = new Setting<>(false);
/**
* 0.0f = not visible, fully transparent
* 0.0f = not visible, fully transparent (instead of setting this to 0, turn off renderCachedChunks)
* 1.0f = fully opaque
*/
public final Setting<Float> cachedChunksOpacity = new Setting<>(0.5f);
@@ -521,6 +596,16 @@ public final class Settings {
*/
public final Setting<Boolean> walkWhileBreaking = new Setting<>(true);
/**
* When a new segment is calculated that doesn't overlap with the current one, but simply begins where the current segment ends,
* splice it on and make a longer combined path. If this setting is off, any planned segment will not be spliced and will instead
* be the "next path" in PathingBehavior, and will only start after this one ends. Turning this off hurts planning ahead,
* because the next segment will exist even if it's very short.
*
* @see #planningTickLookahead
*/
public final Setting<Boolean> splicePath = new Setting<>(true);
/**
* If we are more than 300 movements into the current path, discard the oldest segments, as they are no longer useful
*/
@@ -547,6 +632,68 @@ public final class Settings {
*/
public final Setting<Boolean> exploreForBlocks = new Setting<>(true);
/**
* While exploring the world, offset the closest unloaded chunk by this much in both axes.
* <p>
* This can result in more efficient loading, if you set this to the render distance.
*/
public final Setting<Integer> worldExploringChunkOffset = new Setting<>(0);
/**
* Take the 10 closest chunks, even if they aren't strictly tied for distance metric from origin.
*/
public final Setting<Integer> exploreChunkSetMinimumSize = new Setting<>(10);
/**
* Attempt to maintain Y coordinate while exploring
* <p>
* -1 to disable
*/
public final Setting<Integer> exploreMaintainY = new Setting<>(64);
/**
* Replant nether wart while farming
*/
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);
/**
* false = build from bottom to top
* <p>
* true = build from top to bottom
*/
public final Setting<Boolean> layerOrder = new Setting<>(false);
/**
* How far to move before repeating the build. 0 to disable repeating on a certain axis, 0,0,0 to disable entirely
*/
public final Setting<Vec3i> buildRepeat = new Setting<>(new Vec3i(0, 0, 0));
/**
* Allow standing above a block while mining it, in BuilderProcess
* <p>
* Experimental
*/
public final Setting<Boolean> breakFromAbove = new Setting<>(false);
/**
* As well as breaking from above, set a goal to up and to the side of all blocks to break.
* <p>
* Never turn this on without also turning on breakFromAbove.
*/
public final Setting<Boolean> goalBreakFromAbove = new Setting<>(false);
/**
* While mining, should it also consider dropped items of the correct type as a pathing destination (as well as ore blocks)?
*/
@@ -633,11 +780,10 @@ public final class Settings {
public final Setting<Integer> followRadius = new Setting<>(3);
/**
* true = exploration uses pythagorean distance to choose closest uncached chunk
* <p>
* false = exploration uses manhattan / taxicab distance to choose
* 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> exploreUsePythagorean = new Setting<>(false);
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
@@ -666,7 +812,12 @@ public final class Settings {
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
* {@link Setting#value};
*/
public final Setting<Consumer<ITextComponent>> logger = new Setting<>(Minecraft.getMinecraft().ingameGUI.getChatGUI()::printChatMessage);
public final Setting<Consumer<ITextComponent>> logger = new Setting<>(Minecraft.getInstance().ingameGUI.getChatGUI()::printChatMessage);
/**
* The size of the box that is rendered when the current goal is a GoalYLevel
*/
public final Setting<Double> yLevelBoxSize = new Setting<>(15D);
/**
* The color of the current path
@@ -719,11 +870,12 @@ public final class Settings {
*/
public final List<Setting<?>> allSettings;
public final Map<Setting<?>, Type> settingTypes;
public final class Setting<T> {
public T value;
public final T defaultValue;
private String name;
private final Class<T> klass;
@SuppressWarnings("unchecked")
private Setting(T value) {
@@ -732,7 +884,6 @@ public final class Settings {
}
this.value = value;
this.defaultValue = value;
this.klass = (Class<T>) value.getClass();
}
/**
@@ -750,7 +901,8 @@ public final class Settings {
}
public Class<T> getValueClass() {
return klass;
// noinspection unchecked
return (Class<T>) TypeUtils.resolveBaseClass(getType());
}
@Override
@@ -764,14 +916,21 @@ public final class Settings {
public void reset() {
value = defaultValue;
}
public final Type getType() {
return settingTypes.get(this);
}
}
// here be dragons
Settings() {
Field[] temp = getClass().getFields();
HashMap<String, Setting<?>> tmpByName = new HashMap<>();
Map<String, Setting<?>> tmpByName = new HashMap<>();
List<Setting<?>> tmpAll = new ArrayList<>();
Map<Setting<?>, Type> tmpSettingTypes = new HashMap<>();
try {
for (Field field : temp) {
if (field.getType().equals(Setting.class)) {
@@ -784,6 +943,7 @@ public final class Settings {
}
tmpByName.put(name, setting);
tmpAll.add(setting);
tmpSettingTypes.put(setting, ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]);
}
}
} catch (IllegalAccessException e) {
@@ -791,6 +951,7 @@ public final class Settings {
}
byLowerName = Collections.unmodifiableMap(tmpByName);
allSettings = Collections.unmodifiableList(tmpAll);
settingTypes = Collections.unmodifiableMap(tmpSettingTypes);
}
@SuppressWarnings("unchecked")

View File

@@ -23,9 +23,8 @@ import baritone.api.event.listener.IGameEventListener;
/**
* A behavior is simply a type that is able to listen to events.
*
* @see IGameEventListener
*
* @author Brady
* @see IGameEventListener
* @since 9/23/2018
*/
public interface IBehavior extends AbstractGameEventListener {}

View File

@@ -80,6 +80,13 @@ public interface IPathingBehavior extends IBehavior {
*/
boolean cancelEverything();
/**
* PLEASE never call this
* <p>
* If cancelEverything was like "kill" this is "sudo kill -9". Or shutting off your computer.
*/
void forceCancel();
/**
* Returns the current path, from the current path executor, if there is one.
*

View File

@@ -81,4 +81,6 @@ public interface ICachedWorld {
* in a new thread by default.
*/
void save();
}

View File

@@ -15,9 +15,8 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.cache;
package baritone.api.cache;
import baritone.api.cache.IWaypoint;
import net.minecraft.util.math.BlockPos;
import java.util.Date;
@@ -47,7 +46,7 @@ public class Waypoint implements IWaypoint {
* @param location The waypoint location
* @param creationTimestamp When the waypoint was created
*/
Waypoint(String name, Tag tag, BlockPos location, long creationTimestamp) {
public Waypoint(String name, Tag tag, BlockPos location, long creationTimestamp) {
this.name = name;
this.tag = tag;
this.location = location;

View File

@@ -18,12 +18,11 @@
package baritone.api.event.listener;
import baritone.api.event.events.*;
import io.netty.util.concurrent.GenericFutureListener;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.gui.GuiGameOver;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.entity.Entity;
import net.minecraft.network.Packet;
@@ -45,7 +44,7 @@ public interface IGameEventListener {
* Run once per game tick from before and after the player rotation is sent to the server.
*
* @param event The event
* @see EntityPlayerSP#onUpdate()
* @see EntityPlayerSP#tick()
*/
void onPlayerUpdate(PlayerUpdateEvent event);
@@ -61,14 +60,11 @@ public interface IGameEventListener {
* Runs before and after whenever a chunk is either loaded, unloaded, or populated.
*
* @param event The event
* @see WorldClient#doPreChunk(int, int, boolean)
*/
void onChunkEvent(ChunkEvent event);
/**
* Runs once per world render pass. Two passes are made when {@link GameSettings#anaglyph} is on.
* <p>
* <b>Note:</b> {@link GameSettings#anaglyph} has been removed in Minecraft 1.13
* Runs once per world render pass.
*
* @param event The event
*/
@@ -78,7 +74,7 @@ public interface IGameEventListener {
* Runs before and after whenever a new world is loaded
*
* @param event The event
* @see Minecraft#loadWorld(WorldClient, String)
* @see Minecraft#loadWorld(WorldClient, GuiScreen)
*/
void onWorldEvent(WorldEvent event);
@@ -87,7 +83,6 @@ public interface IGameEventListener {
*
* @param event The event
* @see Packet
* @see GenericFutureListener
*/
void onSendPacket(PacketEvent event);
@@ -96,7 +91,6 @@ public interface IGameEventListener {
*
* @param event The event
* @see Packet
* @see GenericFutureListener
*/
void onReceivePacket(PacketEvent event);
@@ -110,10 +104,10 @@ public interface IGameEventListener {
void onPlayerRotationMove(RotationMoveEvent event);
/**
* Called whenever the sprint keybind state is checked in {@link EntityPlayerSP#onLivingUpdate}
* Called whenever the sprint keybind state is checked in {@link EntityPlayerSP#livingTick}
*
* @param event The event
* @see EntityPlayerSP#onLivingUpdate()
* @see EntityPlayerSP#livingTick()
*/
void onPlayerSprintState(SprintStateEvent event);

View File

@@ -61,6 +61,6 @@ public class GoalNear implements Goal, IGoalRenderPos {
", y=" + y +
", z=" + z +
", rangeSq=" + rangeSq +
'}';
"}";
}
}

View File

@@ -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 +
"}";
}
}

View File

@@ -31,17 +31,17 @@ public class GoalTwoBlocks implements Goal, IGoalRenderPos {
/**
* The X block position of this goal
*/
private final int x;
protected final int x;
/**
* The Y block position of this goal
*/
private final int y;
protected final int y;
/**
* The Z block position of this goal
*/
private final int z;
protected final int z;
public GoalTwoBlocks(BlockPos pos) {
this(pos.getX(), pos.getY(), pos.getZ());

View File

@@ -29,7 +29,7 @@ public class GoalYLevel implements Goal, ActionCosts {
/**
* The target Y level
*/
private final int level;
public final int level;
public GoalYLevel(int level) {
this.level = level;

View File

@@ -18,6 +18,8 @@
package baritone.api.process;
import baritone.api.utils.ISchematic;
import net.minecraft.client.Minecraft;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import java.io.File;
@@ -46,4 +48,15 @@ public interface IBuilderProcess extends IBaritoneProcess {
* @return Whether or not the schematic was able to load from file
*/
boolean build(String name, File schematic, Vec3i origin);
default boolean build(String schematicFile, BlockPos origin) {
File file = new File(new File(Minecraft.getInstance().gameDir, "schematics"), schematicFile);
return build(schematicFile, file, origin);
}
void pause();
void resume();
void clearArea(BlockPos corner1, BlockPos corner2);
}

View File

@@ -0,0 +1,26 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.process;
import java.nio.file.Path;
public interface IExploreProcess extends IBaritoneProcess {
void explore(int centerX, int centerZ);
void applyJsonFilter(Path path, boolean invert) throws Exception;
}

View File

@@ -0,0 +1,22 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.process;
public interface IFarmProcess extends IBaritoneProcess {
void farm();
}

View File

@@ -25,4 +25,6 @@ import net.minecraft.block.Block;
public interface IGetToBlockProcess extends IBaritoneProcess {
void getToBlock(Block block);
boolean blacklistClosest();
}

View File

@@ -51,5 +51,10 @@ public enum PathingCommandType {
* <p>
* Cancel the current path if the goals are not equal
*/
FORCE_REVALIDATE_GOAL_AND_PATH
FORCE_REVALIDATE_GOAL_AND_PATH,
/**
* Go and ask the next process what to do
*/
DEFER
}

View File

@@ -61,6 +61,8 @@ public final class BetterBlockPos extends BlockPos {
}
public static long longHash(int x, int y, int z) {
// TODO use the same thing as BlockPos.fromLong();
// invertibility would be incredibly useful
/*
* This is the hashcode implementation of Vec3i (the superclass of the class which I shall not name)
*

View File

@@ -0,0 +1,67 @@
/*
* 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 net.minecraft.util.registry.IRegistry;
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 = IRegistry.BLOCK.getKey(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) {
if (name.equals("lit_redstone_ore")) { // workaround for Impact 4.6 only
return stringToBlockRequired("redstone_ore");
}
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 = IRegistry.BLOCK.get(ResourceLocation.tryCreate(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() {}
}

View File

@@ -15,41 +15,35 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.utils;
package baritone.api.utils;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.Settings;
import baritone.api.behavior.IPathingBehavior;
import baritone.api.cache.IRememberedInventory;
import baritone.api.cache.IWaypoint;
import baritone.api.cache.Waypoint;
import baritone.api.event.events.ChatEvent;
import baritone.api.event.listener.AbstractGameEventListener;
import baritone.api.pathing.goals.*;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.process.IBaritoneProcess;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.SettingsUtil;
import baritone.behavior.Behavior;
import baritone.behavior.PathingBehavior;
import baritone.cache.ChunkPacker;
import baritone.cache.Waypoint;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.Moves;
import baritone.process.CustomGoalProcess;
import baritone.utils.pathing.SegmentedCalculator;
import baritone.api.process.ICustomGoalProcess;
import baritone.api.process.IGetToBlockProcess;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ChunkProviderClient;
import net.minecraft.crash.CrashReport;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.Chunk;
import java.nio.file.Path;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ExampleBaritoneControl extends Behavior implements Helper {
public class ExampleBaritoneControl implements Helper, AbstractGameEventListener {
private static final String HELP_MSG =
"baritone - Output settings into chat\n" +
@@ -73,6 +67,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
"get - Same as list\n" +
"show - Same as list\n" +
"save - Saves a waypoint (works but don't try to make sense of it)\n" +
"delete - Deletes a waypoint\n" +
"goto - Paths towards specified block or waypoint\n" +
"spawn - Paths towards world spawn or your most recent bed right-click\n" +
"sethome - Sets \"home\"\n" +
@@ -83,21 +78,26 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
private static final String COMMAND_PREFIX = "#";
public ExampleBaritoneControl(Baritone baritone) {
super(baritone);
public final IBaritone baritone;
public final IPlayerContext ctx;
public ExampleBaritoneControl(IBaritone baritone) {
this.baritone = baritone;
this.ctx = baritone.getPlayerContext();
baritone.getGameEventHandler().registerEventListener(this);
}
@Override
public void onSendChatMessage(ChatEvent event) {
String msg = event.getMessage();
if (Baritone.settings().prefixControl.value && msg.startsWith(COMMAND_PREFIX)) {
if (BaritoneAPI.getSettings().prefixControl.value && msg.startsWith(COMMAND_PREFIX)) {
if (!runCommand(msg.substring(COMMAND_PREFIX.length()))) {
logDirect("Invalid command");
}
event.cancel(); // always cancel if using prefixControl
return;
}
if (!Baritone.settings().chatControl.value && !Baritone.settings().removePrefix.value) {
if (!BaritoneAPI.getSettings().chatControl.value && !BaritoneAPI.getSettings().removePrefix.value) {
return;
}
if (runCommand(msg)) {
@@ -107,20 +107,20 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
public boolean runCommand(String msg0) { // you may think this can be private, but impcat calls it from .b =)
String msg = msg0.toLowerCase(Locale.US).trim(); // don't reassign the argument LOL
PathingBehavior pathingBehavior = baritone.getPathingBehavior();
CustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
List<Settings.Setting<Boolean>> toggleable = Baritone.settings().getAllValuesByType(Boolean.class);
IPathingBehavior pathingBehavior = baritone.getPathingBehavior();
ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
List<Settings.Setting<Boolean>> toggleable = BaritoneAPI.getSettings().getAllValuesByType(Boolean.class);
for (Settings.Setting<Boolean> setting : toggleable) {
if (msg.equalsIgnoreCase(setting.getName())) {
setting.value ^= true;
logDirect("Toggled " + setting.getName() + " to " + setting.value);
SettingsUtil.save(Baritone.settings());
SettingsUtil.save(BaritoneAPI.getSettings());
return true;
}
}
if (msg.equals("baritone") || msg.equals("modifiedsettings") || msg.startsWith("settings m") || msg.equals("modified")) {
logDirect("All settings that have been modified from their default values:");
for (Settings.Setting<?> setting : SettingsUtil.modifiedSettings(Baritone.settings())) {
for (Settings.Setting<?> setting : SettingsUtil.modifiedSettings(BaritoneAPI.getSettings())) {
logDirect(setting.toString());
}
return true;
@@ -130,15 +130,15 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
try {
int page = Integer.parseInt(rest.trim());
int min = page * 10;
int max = Math.min(Baritone.settings().allSettings.size(), (page + 1) * 10);
int max = Math.min(BaritoneAPI.getSettings().allSettings.size(), (page + 1) * 10);
logDirect("Settings " + min + " to " + (max - 1) + ":");
for (int i = min; i < max; i++) {
logDirect(Baritone.settings().allSettings.get(i).toString());
logDirect(BaritoneAPI.getSettings().allSettings.get(i).toString());
}
} catch (Exception ex) { // NumberFormatException | ArrayIndexOutOfBoundsException and probably some others I'm forgetting lol
ex.printStackTrace();
logDirect("All settings:");
for (Settings.Setting<?> setting : Baritone.settings().allSettings) {
for (Settings.Setting<?> setting : BaritoneAPI.getSettings().allSettings) {
logDirect(setting.toString());
}
logDirect("To get one page of ten settings at a time, do settings <num>");
@@ -154,26 +154,26 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
if (msg.contains(" ")) {
String settingName = msg.substring(0, msg.indexOf(' '));
String settingValue = msg.substring(msg.indexOf(' ') + 1);
Settings.Setting setting = Baritone.settings().byLowerName.get(settingName);
Settings.Setting setting = BaritoneAPI.getSettings().byLowerName.get(settingName);
if (setting != null) {
if (settingValue.equals("reset")) {
logDirect("Resetting setting " + settingName + " to default value.");
setting.reset();
} else {
try {
SettingsUtil.parseAndApply(Baritone.settings(), settingName, settingValue);
SettingsUtil.parseAndApply(BaritoneAPI.getSettings(), settingName, settingValue);
} catch (Exception ex) {
logDirect("Unable to parse setting");
return true;
}
}
SettingsUtil.save(Baritone.settings());
SettingsUtil.save(BaritoneAPI.getSettings());
logDirect(setting.toString());
return true;
}
}
if (Baritone.settings().byLowerName.containsKey(msg)) {
Settings.Setting<?> setting = Baritone.settings().byLowerName.get(msg);
if (BaritoneAPI.getSettings().byLowerName.containsKey(msg)) {
Settings.Setting<?> setting = BaritoneAPI.getSettings().byLowerName.get(msg);
logDirect(setting.toString());
return true;
}
@@ -197,6 +197,16 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
logDirect("Goal: " + goal);
return true;
}
if (msg.equals("crash")) {
StringBuilder meme = new StringBuilder();
CrashReport rep = new CrashReport("Manually triggered debug crash", new Throwable());
mc.addGraphicsAndWorldToCrashReport(rep);
rep.getSectionsInStringBuilder(meme);
System.out.println(meme);
logDirect(meme.toString());
logDirect("ok");
return true;
}
if (msg.equals("path")) {
if (pathingBehavior.getGoal() == null) {
logDirect("No goal.");
@@ -209,7 +219,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
}
return true;
}
if (msg.equals("fullpath")) {
/*if (msg.equals("fullpath")) {
if (pathingBehavior.getGoal() == null) {
logDirect("No goal.");
} else {
@@ -225,7 +235,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
});
}
return true;
}
}*/
if (msg.equals("proc")) {
Optional<IBaritoneProcess> proc = baritone.getPathingControlManager().mostRecentInControl();
if (!proc.isPresent()) {
@@ -256,7 +266,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
int count = 0;
for (int x = playerChunkX - 40; x <= playerChunkX + 40; x++) {
for (int z = playerChunkZ - 40; z <= playerChunkZ + 40; z++) {
Chunk chunk = cli.getLoadedChunk(x, z);
Chunk chunk = cli.getChunk(x, z, false, false);
if (chunk != null) {
count++;
baritone.getWorldProvider().getCurrentWorld().getCachedWorld().queueForPacking(chunk);
@@ -283,7 +293,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
return true;
}
if (msg.equals("come")) {
customGoalProcess.setGoalAndPath(new GoalBlock(new BlockPos(mc.getRenderViewEntity())));
customGoalProcess.setGoalAndPath(new GoalBlock(new BlockPos(Helper.mc.getRenderViewEntity())));
logDirect("Coming");
return true;
}
@@ -334,7 +344,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
if (suffix.isEmpty()) {
// clear the area from the current goal to here
Goal goal = baritone.getPathingBehavior().getGoal();
if (goal == null || !(goal instanceof GoalBlock)) {
if (!(goal instanceof GoalBlock)) {
logDirect("Need to specify goal of opposite corner");
return true;
}
@@ -353,41 +363,41 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
baritone.getBuilderProcess().clearArea(corner1, corner2);
return true;
}
if (msg.equals("resume")) {
baritone.getBuilderProcess().resume();
logDirect("resumed");
return true;
}
if (msg.equals("pause")) {
baritone.getBuilderProcess().pause();
logDirect("paused");
return true;
}
if (msg.equals("reset")) {
for (Settings.Setting setting : Baritone.settings().allSettings) {
for (Settings.Setting setting : BaritoneAPI.getSettings().allSettings) {
setting.reset();
}
SettingsUtil.save(Baritone.settings());
SettingsUtil.save(BaritoneAPI.getSettings());
logDirect("Baritone settings reset");
return true;
}
if (msg.equals("tunnel")) {
customGoalProcess.setGoalAndPath(new GoalStrictDirection(ctx.playerFeet(), ctx.player().getHorizontalFacing()));
logDirect("tunneling");
return true;
}
if (msg.equals("render")) {
BetterBlockPos pf = ctx.playerFeet();
Minecraft.getMinecraft().renderGlobal.markBlockRangeForRenderUpdate(pf.x - 500, pf.y - 500, pf.z - 500, pf.x + 500, pf.y + 500, pf.z + 500);
Minecraft.getInstance().worldRenderer.markBlockRangeForRenderUpdate(pf.x - 500, pf.y - 500, pf.z - 500, pf.x + 500, pf.y + 500, pf.z + 500);
logDirect("okay");
return true;
}
if (msg.equals("echest")) {
Optional<List<ItemStack>> contents = baritone.getMemoryBehavior().echest();
if (contents.isPresent()) {
logDirect("echest contents:");
log(contents.get());
} else {
logDirect("echest contents unknown");
}
if (msg.equals("farm")) {
baritone.getFarmProcess().farm();
logDirect("farming");
return true;
}
if (msg.equals("chests")) {
System.out.println(baritone.getWorldProvider());
System.out.println(baritone.getWorldProvider().getCurrentWorld());
System.out.println(baritone.getWorldProvider().getCurrentWorld().getContainerMemory());
System.out.println(baritone.getWorldProvider().getCurrentWorld().getContainerMemory().getRememberedInventories());
System.out.println(baritone.getWorldProvider().getCurrentWorld().getContainerMemory().getRememberedInventories().entrySet());
System.out.println(baritone.getWorldProvider().getCurrentWorld().getContainerMemory().getRememberedInventories().entrySet());
for (Map.Entry<BlockPos, IRememberedInventory> entry : baritone.getWorldProvider().getCurrentWorld().getContainerMemory().getRememberedInventories().entrySet()) {
logDirect(entry.getKey() + "");
log(entry.getValue().getContents());
@@ -406,8 +416,8 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
toFollow = ctx.getSelectedEntity();
} else {
for (EntityPlayer pl : ctx.world().playerEntities) {
String theirName = pl.getName().trim().toLowerCase();
if (!theirName.equals(ctx.player().getName().trim().toLowerCase()) && (theirName.contains(name) || name.contains(theirName))) { // don't follow ourselves lol
String theirName = pl.getName().getString().trim().toLowerCase();
if (!theirName.equals(ctx.player().getName().getString().trim().toLowerCase()) && (theirName.contains(name) || name.contains(theirName))) { // don't follow ourselves lol
toFollow = Optional.of(pl);
}
}
@@ -417,10 +427,33 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
return true;
}
Entity effectivelyFinal = toFollow.get();
baritone.getFollowProcess().follow(x -> effectivelyFinal.equals(x));
baritone.getFollowProcess().follow(effectivelyFinal::equals);
logDirect("Following " + toFollow.get());
return true;
}
if (msg.startsWith("explorefilter")) {
// explorefilter blah.json
// means that entries in blah.json are already explored
// explorefilter blah.json invert
// means that entries in blah.json are NOT already explored
String path = msg.substring("explorefilter".length()).trim();
String[] parts = path.split(" ");
Path path1 = Minecraft.getInstance().gameDir.toPath().resolve(parts[0]);
boolean invert = parts.length > 1;
try {
baritone.getExploreProcess().applyJsonFilter(path1, invert);
logDirect("Loaded filter. Inverted: " + invert);
if (invert) {
logDirect("Chunks on this list will be treated as possibly unexplored, all others will be treated as certainly explored");
} else {
logDirect("Chunks on this list will be treated as certainly explored, all others will be treated as possibly unexplored");
}
} catch (Exception e) {
e.printStackTrace();
logDirect("Unable to load " + path1);
}
return true;
}
if (msg.equals("reloadall")) {
baritone.getWorldProvider().getCurrentWorld().getCachedWorld().reloadAllFromDisk();
logDirect("ok");
@@ -446,14 +479,27 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
logDirect("Exploring from " + centerX + "," + centerZ);
return true;
}
if (msg.equals("blacklist")) {
IGetToBlockProcess proc = baritone.getGetToBlockProcess();
if (!proc.isActive()) {
logDirect("GetToBlockProcess is not currently active");
return true;
}
if (proc.blacklistClosest()) {
logDirect("Blacklisted closest instances");
} else {
logDirect("No known locations, unable to blacklist");
}
return true;
}
if (msg.startsWith("find")) {
String blockType = msg.substring(4).trim();
ArrayList<BlockPos> locs = baritone.getWorldProvider().getCurrentWorld().getCachedWorld().getLocationsOf(blockType, 1, ctx.playerFeet().getX(), ctx.playerFeet().getZ(), 4);
logDirect("Have " + locs.size() + " locations");
for (BlockPos pos : locs) {
Block actually = BlockStateInterface.get(ctx, pos).getBlock();
if (!ChunkPacker.blockToString(actually).equalsIgnoreCase(blockType)) {
System.out.println("Was looking for " + blockType + " but actually found " + actually + " " + ChunkPacker.blockToString(actually));
Block actually = ctx.world().getBlockState(pos).getBlock();
if (!BlockUtils.blockToString(actually).equalsIgnoreCase(blockType)) {
logDebug("Was looking for " + blockType + " but actually found " + actually + " " + BlockUtils.blockToString(actually));
}
}
return true;
@@ -462,13 +508,13 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
String[] blockTypes = msg.substring(4).trim().split(" ");
try {
int quantity = Integer.parseInt(blockTypes[1]);
Block block = ChunkPacker.stringToBlockRequired(blockTypes[0]);
Block block = BlockUtils.stringToBlockRequired(blockTypes[0]);
baritone.getMineProcess().mine(quantity, block);
logDirect("Will mine " + quantity + " " + blockTypes[0]);
return true;
} catch (NumberFormatException | ArrayIndexOutOfBoundsException | NullPointerException ex) {}
for (String s : blockTypes) {
if (ChunkPacker.stringToBlockNullable(s) == null) {
if (BlockUtils.stringToBlockNullable(s) == null) {
logDirect(s + " isn't a valid block name");
return true;
}
@@ -479,12 +525,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
return true;
}
if (msg.equals("click")) {
new Thread(() -> {
try {
Thread.sleep(100);
mc.addScheduledTask(() -> mc.displayGuiScreen(new GuiClick()));
} catch (Exception ignored) {}
}).start();
baritone.openClick();
logDirect("aight dude");
return true;
}
@@ -504,9 +545,9 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
// for example, "show deaths"
waypointType = waypointType.substring(0, waypointType.length() - 1);
}
Waypoint.Tag tag = Waypoint.Tag.fromString(waypointType);
IWaypoint.Tag tag = IWaypoint.Tag.fromString(waypointType);
if (tag == null) {
logDirect("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
logDirect("Not a valid tag. Tags are: " + Arrays.asList(IWaypoint.Tag.values()).toString().toLowerCase());
return true;
}
Set<IWaypoint> waypoints = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getByTag(tag);
@@ -537,21 +578,32 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
}
name = parts[0];
}
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint(name, Waypoint.Tag.USER, pos));
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint(name, IWaypoint.Tag.USER, pos));
logDirect("Saved user defined position " + pos + " under name '" + name + "'. Say 'goto " + name + "' to set goal, say 'list user' to list custom waypoints.");
return true;
}
if (msg.startsWith("delete")) {
String name = msg.substring(6).trim();
IWaypoint waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getAllWaypoints().stream().filter(w -> w.getTag() == IWaypoint.Tag.USER && w.getName().equalsIgnoreCase(name)).findFirst().orElse(null);
if (waypoint == null) {
logDirect("No user defined position under the name '" + name + "' found.");
return true;
}
baritone.getWorldProvider().getCurrentWorld().getWaypoints().removeWaypoint(waypoint);
logDirect("Deleted user defined position under name '" + name + "'.");
return true;
}
if (msg.startsWith("goto")) {
String waypointType = msg.substring(4).trim();
if (waypointType.endsWith("s") && Waypoint.Tag.fromString(waypointType.substring(0, waypointType.length() - 1)) != null) {
if (waypointType.endsWith("s") && IWaypoint.Tag.fromString(waypointType.substring(0, waypointType.length() - 1)) != null) {
// for example, "show deaths"
waypointType = waypointType.substring(0, waypointType.length() - 1);
}
Waypoint.Tag tag = Waypoint.Tag.fromString(waypointType);
IWaypoint.Tag tag = IWaypoint.Tag.fromString(waypointType);
IWaypoint waypoint;
if (tag == null) {
String mining = waypointType;
Block block = ChunkPacker.stringToBlockNullable(mining);
Block block = BlockUtils.stringToBlockNullable(mining);
//logDirect("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
if (block == null) {
waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getAllWaypoints().stream().filter(w -> w.getName().equalsIgnoreCase(mining)).max(Comparator.comparingLong(IWaypoint::getCreationTimestamp)).orElse(null);
@@ -574,12 +626,12 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
return true;
}
}
Goal goal = waypoint.getTag() == Waypoint.Tag.BED ? new GoalGetToBlock(waypoint.getLocation()) : new GoalBlock(waypoint.getLocation());
Goal goal = waypoint.getTag() == IWaypoint.Tag.BED ? new GoalGetToBlock(waypoint.getLocation()) : new GoalBlock(waypoint.getLocation());
customGoalProcess.setGoalAndPath(goal);
return true;
}
if (msg.equals("spawn") || msg.equals("bed")) {
IWaypoint waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getMostRecentByTag(Waypoint.Tag.BED);
IWaypoint waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getMostRecentByTag(IWaypoint.Tag.BED);
if (waypoint == null) {
BlockPos spawnPoint = ctx.player().getBedLocation();
// for some reason the default spawnpoint is underground sometimes
@@ -594,12 +646,12 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
return true;
}
if (msg.equals("sethome")) {
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("", Waypoint.Tag.HOME, ctx.playerFeet()));
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("", IWaypoint.Tag.HOME, ctx.playerFeet()));
logDirect("Saved. Say home to set goal.");
return true;
}
if (msg.equals("home")) {
IWaypoint waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getMostRecentByTag(Waypoint.Tag.HOME);
IWaypoint waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getMostRecentByTag(IWaypoint.Tag.HOME);
if (waypoint == null) {
logDirect("home not saved");
} else {
@@ -609,23 +661,6 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
}
return true;
}
if (msg.equals("costs")) {
List<Movement> moves = Stream.of(Moves.values()).map(x -> x.apply0(new CalculationContext(baritone), ctx.playerFeet())).collect(Collectors.toCollection(ArrayList::new));
while (moves.contains(null)) {
moves.remove(null);
}
moves.sort(Comparator.comparingDouble(move -> move.getCost(new CalculationContext(baritone))));
for (Movement move : moves) {
String[] parts = move.getClass().toString().split("\\.");
double cost = move.getCost();
String strCost = cost + "";
if (cost >= ActionCosts.COST_INF) {
strCost = "IMPOSSIBLE";
}
logDirect(parts[parts.length - 1] + " " + move.getDest().getX() + "," + move.getDest().getY() + "," + move.getDest().getZ() + " " + strCost);
}
return true;
}
if (msg.equals("damn")) {
logDirect("daniel");
}
@@ -639,7 +674,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
private void log(List<ItemStack> stacks) {
for (ItemStack stack : stacks) {
if (!stack.isEmpty()) {
logDirect(stack.getCount() + "x " + stack.getDisplayName() + "@" + stack.getItemDamage());
logDirect(stack.getCount() + "x " + stack.getDisplayName() + "@" + stack.getDamage());
}
}
}
@@ -647,18 +682,20 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
private Goal parseGoal(String[] params) {
Goal goal;
try {
BetterBlockPos playerFeet = ctx.playerFeet();
switch (params.length) {
case 0:
goal = new GoalBlock(ctx.playerFeet());
goal = new GoalBlock(playerFeet);
break;
case 1:
goal = new GoalYLevel(Integer.parseInt(params[0]));
goal = new GoalYLevel(parseOrDefault(params[0], playerFeet.y));
break;
case 2:
goal = new GoalXZ(Integer.parseInt(params[0]), Integer.parseInt(params[1]));
goal = new GoalXZ(parseOrDefault(params[0], playerFeet.x), parseOrDefault(params[1], playerFeet.z));
break;
case 3:
goal = new GoalBlock(new BlockPos(Integer.parseInt(params[0]), Integer.parseInt(params[1]), Integer.parseInt(params[2])));
goal = new GoalBlock(new BlockPos(parseOrDefault(params[0], playerFeet.x), parseOrDefault(params[1], playerFeet.y), parseOrDefault(params[2], playerFeet.z)));
break;
default:
logDirect("unable to understand lol");

View File

@@ -15,9 +15,9 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.utils;
package baritone.api.utils;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import net.minecraft.client.Minecraft;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
@@ -42,7 +42,7 @@ public interface Helper {
TextFormatting.GRAY
));
Minecraft mc = Minecraft.getMinecraft();
Minecraft mc = Minecraft.getInstance();
/**
* Send a message to chat only if chatDebug is on
@@ -50,7 +50,7 @@ public interface Helper {
* @param message The message to display in chat
*/
default void logDebug(String message) {
if (!Baritone.settings().chatDebug.value) {
if (!BaritoneAPI.getSettings().chatDebug.value) {
//System.out.println("Suppressed debug message:");
//System.out.println(message);
return;
@@ -64,9 +64,9 @@ public interface Helper {
* @param message The message to display in chat
*/
default void logDirect(String message) {
ITextComponent component = MESSAGE_PREFIX.createCopy();
ITextComponent component = MESSAGE_PREFIX.shallowCopy();
component.getStyle().setColor(TextFormatting.GRAY);
component.appendSibling(new TextComponentString(" " + message));
Minecraft.getMinecraft().addScheduledTask(() -> Baritone.settings().logger.value.accept(component));
Minecraft.getInstance().addScheduledTask(() -> BaritoneAPI.getSettings().logger.value.accept(component));
}
}

View File

@@ -71,20 +71,26 @@ public interface IPlayerContext {
* @return The position of the highlighted block
*/
default Optional<BlockPos> getSelectedBlock() {
if (objectMouseOver() != null && objectMouseOver().typeOfHit == RayTraceResult.Type.BLOCK) {
return Optional.of(objectMouseOver().getBlockPos());
RayTraceResult result = objectMouseOver();
if (result != null && result.type == RayTraceResult.Type.BLOCK) {
return Optional.of(result.getBlockPos());
}
return Optional.empty();
}
default boolean isLookingAt(BlockPos pos) {
return getSelectedBlock().equals(Optional.of(pos));
}
/**
* Returns the entity that the crosshair is currently placed over. Updated once per tick.
*
* @return The entity
*/
default Optional<Entity> getSelectedEntity() {
if (objectMouseOver() != null && objectMouseOver().typeOfHit == RayTraceResult.Type.ENTITY) {
return Optional.of(objectMouseOver().entityHit);
RayTraceResult result = objectMouseOver();
if (result != null && result.type == RayTraceResult.Type.ENTITY) {
return Optional.of(result.entity);
}
return Optional.empty();
}

View File

@@ -18,6 +18,7 @@
package baritone.api.utils;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.EnumFacing;
/**
* Basic representation of a schematic. Provides the dimensions and
@@ -44,6 +45,19 @@ public interface ISchematic {
return x >= 0 && x < widthX() && y >= 0 && y < heightY() && z >= 0 && z < lengthZ();
}
default int size(EnumFacing.Axis axis) {
switch (axis) {
case X:
return widthX();
case Y:
return heightY();
case Z:
return lengthZ();
default:
throw new UnsupportedOperationException(axis + "");
}
}
/**
* Returns the desired block state at a given (X, Y, Z) position relative to the origin (0, 0, 0).
*

View File

@@ -15,15 +15,23 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.gradle.util;
package baritone.api.utils;
import com.google.gson.annotations.SerializedName;
/**
* All credits go to AsmLibGradle and its contributors.
*
* @see <a href="https://github.com/pozzed/AsmLibGradle/blob/8f917dbc3939eab7a3d9daf54d9d285fdf34f4b2/src/main/java/net/futureclient/asmlib/forgegradle/MappingType.java">Original Source</a>
* Need a non obfed chunkpos that we can load using GSON
*/
public enum MappingType {
SEARGE,
NOTCH,
CUSTOM // forgegradle
}
public class MyChunkPos {
@SerializedName("x")
public int x;
@SerializedName("y")
public int z;
@Override
public String toString() {
return x + ", " + z;
}
}

View File

@@ -18,6 +18,7 @@
package baritone.api.utils;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.RayTraceFluidMode;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
@@ -40,13 +41,13 @@ public final class RayTraceUtils {
* @return The calculated raytrace result
*/
public static RayTraceResult rayTraceTowards(Entity entity, Rotation rotation, double blockReachDistance) {
Vec3d start = entity.getPositionEyes(1.0F);
Vec3d start = entity.getEyePosition(1.0F);
Vec3d direction = RotationUtils.calcVec3dFromRotation(rotation);
Vec3d end = start.add(
direction.x * blockReachDistance,
direction.y * blockReachDistance,
direction.z * blockReachDistance
);
return entity.world.rayTraceBlocks(start, end, false, false, true);
return entity.world.rayTraceBlocks(start, end, RayTraceFluidMode.NEVER, false, true);
}
}

View File

@@ -36,6 +36,9 @@ public class Rotation {
public Rotation(float yaw, float pitch) {
this.yaw = yaw;
this.pitch = pitch;
if (Float.isInfinite(yaw) || Float.isNaN(yaw) || Float.isInfinite(pitch) || Float.isNaN(pitch)) {
throw new IllegalStateException(yaw + " " + pitch);
}
}
/**

View File

@@ -23,7 +23,13 @@ import net.minecraft.block.BlockFire;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.*;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import java.util.Optional;
@@ -154,7 +160,7 @@ public final class RotationUtils {
*/
public static Optional<Rotation> reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(entity);
if (pos.equals(baritone.getPlayerContext().getSelectedBlock().orElse(null))) {
if (baritone.getPlayerContext().isLookingAt(pos)) {
/*
* why add 0.0001?
* to indicate that we actually have a desired pitch
@@ -174,11 +180,14 @@ public final class RotationUtils {
}
IBlockState state = entity.world.getBlockState(pos);
AxisAlignedBB aabb = state.getBoundingBox(entity.world, pos);
VoxelShape shape = state.getShape(entity.world, pos);
if (shape.isEmpty()) {
shape = VoxelShapes.fullCube();
}
for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) {
double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x);
double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y);
double zDiff = aabb.minZ * sideOffset.z + aabb.maxZ * (1 - sideOffset.z);
double xDiff = shape.getStart(EnumFacing.Axis.X) * sideOffset.x + shape.getEnd(EnumFacing.Axis.X) * (1 - sideOffset.x);
double yDiff = shape.getStart(EnumFacing.Axis.Y) * sideOffset.y + shape.getEnd(EnumFacing.Axis.Y) * (1 - sideOffset.y);
double zDiff = shape.getStart(EnumFacing.Axis.Z) * sideOffset.z + shape.getEnd(EnumFacing.Axis.Z) * (1 - sideOffset.z);
possibleRotation = reachableOffset(entity, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff), blockReachDistance);
if (possibleRotation.isPresent()) {
return possibleRotation;
@@ -199,10 +208,10 @@ public final class RotationUtils {
* @return The optional rotation
*/
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance) {
Rotation rotation = calcRotationFromVec3d(entity.getPositionEyes(1.0F), offsetPos, new Rotation(entity.rotationYaw, entity.rotationPitch));
Rotation rotation = calcRotationFromVec3d(entity.getEyePosition(1.0F), offsetPos, new Rotation(entity.rotationYaw, entity.rotationPitch));
RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, rotation, blockReachDistance);
//System.out.println(result);
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
if (result != null && result.type == RayTraceResult.Type.BLOCK) {
if (result.getBlockPos().equals(pos)) {
return Optional.of(rotation);
}

View File

@@ -18,32 +18,38 @@
package baritone.api.utils;
import baritone.api.Settings;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.item.Item;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.registry.IRegistry;
import net.minecraft.util.math.Vec3i;
import java.awt.*;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static net.minecraft.client.Minecraft.getMinecraft;
public class SettingsUtil {
private static final Path SETTINGS_PATH = Minecraft.getInstance().gameDir.toPath().resolve("baritone").resolve("settings.txt");
private static final Pattern SETTING_PATTERN = Pattern.compile("^(?<setting>[^ ]+) +(?<value>.+)"); // key and value split by the first space
private static final Path SETTINGS_PATH = getMinecraft().gameDir.toPath().resolve("baritone").resolve("settings.txt");
private static final Pattern SETTING_PATTERN = Pattern.compile("^(?<setting>[^ ]+) +(?<value>[^ ]+)"); // 2 words separated by spaces
private static final Map<Class<?>, SettingsIO> map;
private static boolean isComment(String line) {
return line.startsWith("#") || line.startsWith("//");
@@ -79,6 +85,8 @@ public class SettingsUtil {
ex.printStackTrace();
}
});
} catch (NoSuchFileException ignored) {
System.out.println("Baritone settings file not found, resetting.");
} catch (Exception ex) {
System.out.println("Exception while reading Baritone settings, some settings may be reset to default values!");
ex.printStackTrace();
@@ -118,11 +126,11 @@ public class SettingsUtil {
if (setting.getName().equals("logger")) {
return "logger";
}
SettingsIO io = map.get(setting.getValueClass());
Parser io = Parser.getParser(setting.getType());
if (io == null) {
throw new IllegalStateException("Missing " + setting.getValueClass() + " " + setting.getName());
}
return setting.getName() + " " + io.toString.apply(setting.value);
return setting.getName() + " " + io.toString(new ParserContext(setting), setting.value);
}
public static void parseAndApply(Settings settings, String settingName, String settingValue) throws IllegalStateException, NumberFormatException {
@@ -131,45 +139,131 @@ public class SettingsUtil {
throw new IllegalStateException("No setting by that name");
}
Class intendedType = setting.getValueClass();
SettingsIO ioMethod = map.get(intendedType);
Object parsed = ioMethod.parser.apply(settingValue);
ISettingParser ioMethod = Parser.getParser(setting.getType());
Object parsed = ioMethod.parse(new ParserContext(setting), settingValue);
if (!intendedType.isInstance(parsed)) {
throw new IllegalStateException(ioMethod + " parser returned incorrect type, expected " + intendedType + " got " + parsed + " which is " + parsed.getClass());
}
setting.value = parsed;
}
private enum SettingsIO {
private interface ISettingParser<T> {
T parse(ParserContext context, String raw);
String toString(ParserContext context, T value);
boolean accepts(Type type);
}
private static class ParserContext {
private final Settings.Setting<?> setting;
private ParserContext(Settings.Setting<?> setting) {
this.setting = setting;
}
private Settings.Setting<?> getSetting() {
return this.setting;
}
}
private enum Parser implements ISettingParser {
DOUBLE(Double.class, Double::parseDouble),
BOOLEAN(Boolean.class, Boolean::parseBoolean),
INTEGER(Integer.class, Integer::parseInt),
FLOAT(Float.class, Float::parseFloat),
LONG(Long.class, Long::parseLong),
ENUMFACING(EnumFacing.class, EnumFacing::byName),
COLOR(
Color.class,
str -> new Color(Integer.parseInt(str.split(",")[0]), Integer.parseInt(str.split(",")[1]), Integer.parseInt(str.split(",")[2])),
color -> color.getRed() + "," + color.getGreen() + "," + color.getBlue()
),
VEC3I(
Vec3i.class,
str -> new Vec3i(Integer.parseInt(str.split(",")[0]), Integer.parseInt(str.split(",")[1]), Integer.parseInt(str.split(",")[2])),
vec -> vec.getX() + "," + vec.getY() + "," + vec.getZ()
),
BLOCK(
Block.class,
str -> BlockUtils.stringToBlockRequired(str.trim()),
BlockUtils::blockToString
),
ITEM(
Item.class,
str -> IRegistry.ITEM.get(new ResourceLocation(str.trim())),
item -> IRegistry.ITEM.getKey(item).toString()
),
LIST() {
@Override
public Object parse(ParserContext context, String raw) {
Type type = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
Parser parser = Parser.getParser(type);
return Arrays.stream(raw.split(","))
.map(s -> parser.parse(context, s))
.collect(Collectors.toList());
}
ITEM_LIST(ArrayList.class, str -> Stream.of(str.split(",")).map(Item::getByNameOrId).collect(Collectors.toCollection(ArrayList::new)), list -> ((ArrayList<Item>) list).stream().map(Item.REGISTRY::getNameForObject).map(ResourceLocation::toString).collect(Collectors.joining(","))),
COLOR(Color.class, str -> new Color(Integer.parseInt(str.split(",")[0]), Integer.parseInt(str.split(",")[1]), Integer.parseInt(str.split(",")[2])), color -> color.getRed() + "," + color.getGreen() + "," + color.getBlue());
@Override
public String toString(ParserContext context, Object value) {
Type type = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
Parser parser = Parser.getParser(type);
return ((List<?>) value).stream()
.map(o -> parser.toString(context, o))
.collect(Collectors.joining(","));
}
Class<?> klass;
Function<String, Object> parser;
Function<Object, String> toString;
@Override
public boolean accepts(Type type) {
return List.class.isAssignableFrom(TypeUtils.resolveBaseClass(type));
}
};
<T> SettingsIO(Class<T> klass, Function<String, T> parser) {
private final Class<?> klass;
private final Function<String, Object> parser;
private final Function<Object, String> toString;
Parser() {
this.klass = null;
this.parser = null;
this.toString = null;
}
<T> Parser(Class<T> klass, Function<String, T> parser) {
this(klass, parser, Object::toString);
}
<T> SettingsIO(Class<T> klass, Function<String, T> parser, Function<T, String> toString) {
<T> Parser(Class<T> klass, Function<String, T> parser, Function<T, String> toString) {
this.klass = klass;
this.parser = parser::apply;
this.toString = x -> toString.apply((T) x);
}
}
static {
HashMap<Class<?>, SettingsIO> tempMap = new HashMap<>();
for (SettingsIO type : SettingsIO.values()) {
tempMap.put(type.klass, type);
@Override
public Object parse(ParserContext context, String raw) {
Object parsed = this.parser.apply(raw);
Objects.requireNonNull(parsed);
return parsed;
}
@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);
}
}

View File

@@ -0,0 +1,44 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.utils;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
/**
* @author Brady
* @since 4/20/2019
*/
public final class TypeUtils {
private TypeUtils() {}
/**
* Resolves the "base type" for the specified type. For example, if the specified
* type is {@code List<String>}, then {@code List.class} will be returned. If the
* specified type is already a class, then it is directly returned.
*
* @param type The type to resolve
* @return The base class
*/
public static Class<?> resolveBaseClass(Type type) {
return type instanceof Class ? (Class<?>) type
: type instanceof ParameterizedType ? (Class<?>) ((ParameterizedType) type).getRawType()
: null;
}
}

View File

@@ -20,9 +20,10 @@ package baritone.api.utils;
import net.minecraft.block.BlockFire;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.world.World;
/**
@@ -43,10 +44,16 @@ public final class VecUtils {
*/
public static Vec3d calculateBlockCenter(World world, BlockPos pos) {
IBlockState b = world.getBlockState(pos);
AxisAlignedBB bbox = b.getBoundingBox(world, pos);
double xDiff = (bbox.minX + bbox.maxX) / 2;
double yDiff = (bbox.minY + bbox.maxY) / 2;
double zDiff = (bbox.minZ + bbox.maxZ) / 2;
VoxelShape shape = b.getCollisionShape(world, pos);
if (shape.isEmpty()) {
return getBlockPosCenter(pos);
}
double xDiff = (shape.getStart(EnumFacing.Axis.X) + shape.getEnd(EnumFacing.Axis.X)) / 2;
double yDiff = (shape.getStart(EnumFacing.Axis.Y) + shape.getEnd(EnumFacing.Axis.Y)) / 2;
double zDiff = (shape.getStart(EnumFacing.Axis.Z) + shape.getEnd(EnumFacing.Axis.Z)) / 2;
if (Double.isNaN(xDiff) || Double.isNaN(yDiff) || Double.isNaN(zDiff)) {
throw new IllegalStateException(b + " " + pos + " " + shape);
}
if (b.getBlock() instanceof BlockFire) {//look at bottom of fire when putting it out
yDiff = 0;
}

View File

@@ -0,0 +1,105 @@
/*
* 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.launch;
import com.google.common.base.Strings;
import com.google.gson.GsonBuilder;
import com.mojang.authlib.Agent;
import com.mojang.authlib.exceptions.AuthenticationException;
import com.mojang.authlib.properties.PropertyMap;
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
import com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication;
import net.minecraft.launchwrapper.Launch;
import java.io.File;
import java.lang.reflect.Field;
import java.net.Proxy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Based on GradleStart from ForgeGradle 2.3
*
* @author Brady
* @since 3/11/2019
*/
public class LaunchTesting {
public static void main(String[] args) {
Map<String, String> arguments = new HashMap<>();
hackNatives();
arguments.put("version", "BaritownedDeveloperEnvironment");
arguments.put("assetIndex", System.getenv("assetIndex"));
arguments.put("assetsDir", System.getenv().getOrDefault("assetDirectory", "assets"));
arguments.put("accessToken", "FML");
arguments.put("userProperties", "{}");
arguments.put("tweakClass", System.getenv("tweakClass"));
String password = System.getenv("password");
if (password != null && !password.isEmpty()) {
attemptLogin(arguments, System.getenv("username"), System.getenv("password"));
}
List<String> argsArray = new ArrayList<>();
arguments.forEach((k, v) -> {
argsArray.add("--" + k);
argsArray.add(v);
});
Launch.main(argsArray.toArray(new String[0]));
}
private static void hackNatives() {
String paths = System.getProperty("java.library.path");
String nativesDir = System.getenv().get("nativesDirectory");
if (Strings.isNullOrEmpty(paths))
paths = nativesDir;
else
paths += File.pathSeparator + nativesDir;
System.setProperty("java.library.path", paths);
// hack the classloader now.
try {
final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
sysPathsField.setAccessible(true);
sysPathsField.set(null, null);
} catch (Throwable ignored) {}
}
private static void attemptLogin(Map<String, String> argMap, String username, String password) {
YggdrasilUserAuthentication auth = (YggdrasilUserAuthentication) (new YggdrasilAuthenticationService(Proxy.NO_PROXY, "1")).createUserAuthentication(Agent.MINECRAFT);
auth.setUsername(username);
auth.setPassword(password);
try {
auth.logIn();
} catch (AuthenticationException var4) {
throw new RuntimeException(var4);
}
argMap.put("accessToken", auth.getAuthenticatedToken());
argMap.put("uuid", auth.getSelectedProfile().getId().toString().replace("-", ""));
argMap.put("username", auth.getSelectedProfile().getName());
argMap.put("userType", auth.getUserType().getName());
argMap.put("userProperties", (new GsonBuilder()).registerTypeAdapter(PropertyMap.class, new PropertyMap.Serializer()).create().toJson(auth.getUserProperties()));
}
}

View File

@@ -28,7 +28,10 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL11.GL_ONE;
import static org.lwjgl.opengl.GL11.GL_ZERO;
import static org.lwjgl.opengl.GL14.GL_CONSTANT_ALPHA;
import static org.lwjgl.opengl.GL14.GL_ONE_MINUS_CONSTANT_ALPHA;
@Mixin(ChunkRenderContainer.class)
public class MixinChunkRenderContainer {
@@ -41,11 +44,11 @@ public class MixinChunkRenderContainer {
)
)
private BlockPos getPosition(RenderChunk renderChunkIn) {
if (Baritone.settings().renderCachedChunks.value && Minecraft.getMinecraft().getIntegratedServer() == null && Minecraft.getMinecraft().world.getChunk(renderChunkIn.getPosition()).isEmpty()) {
GlStateManager.enableAlpha();
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getInstance().isSingleplayer() && Minecraft.getInstance().world.getChunk(renderChunkIn.getPosition()).isEmpty()) {
GlStateManager.enableAlphaTest();
GlStateManager.enableBlend();
GL14.glBlendColor(0, 0, 0, Baritone.settings().cachedChunksOpacity.value);
GlStateManager.tryBlendFuncSeparate(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA, GL_ONE, GL_ZERO);
GlStateManager.blendFuncSeparate(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA, GL_ONE, GL_ZERO);
}
return renderChunkIn.getPosition();
}

View File

@@ -43,7 +43,7 @@ public abstract class MixinChunkRenderWorker {
)
)
private boolean isChunkExisting(ChunkRenderWorker worker, BlockPos pos, World world) {
if (Baritone.settings().renderCachedChunks.value && Minecraft.getMinecraft().getIntegratedServer() == null) {
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getInstance().isSingleplayer()) {
Baritone baritone = (Baritone) BaritoneAPI.getProvider().getPrimaryBaritone();
IPlayerContext ctx = baritone.getPlayerContext();
if (ctx.player() != null && ctx.world() != null && baritone.bsi != null) {

View File

@@ -23,6 +23,7 @@ import baritone.api.event.events.RotationMoveEvent;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.EntityType;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@@ -44,9 +45,8 @@ public abstract class MixinEntityLivingBase extends Entity {
*/
private RotationMoveEvent jumpRotationEvent;
public MixinEntityLivingBase(World worldIn, RotationMoveEvent jumpRotationEvent) {
super(worldIn);
this.jumpRotationEvent = jumpRotationEvent;
public MixinEntityLivingBase(EntityType<?> entityTypeIn, World worldIn) {
super(entityTypeIn, worldIn);
}
@Inject(

View File

@@ -58,10 +58,10 @@ public class MixinEntityPlayerSP {
}
@Inject(
method = "onUpdate",
method = "tick",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/entity/EntityPlayerSP.isRiding()Z",
target = "net/minecraft/client/entity/EntityPlayerSP.isPassenger()Z",
shift = At.Shift.BY,
by = -3
)
@@ -74,7 +74,7 @@ public class MixinEntityPlayerSP {
}
@Inject(
method = "onUpdate",
method = "tick",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/entity/EntityPlayerSP.onUpdateWalkingPlayer()V",
@@ -90,7 +90,7 @@ public class MixinEntityPlayerSP {
}
@Redirect(
method = "onLivingUpdate",
method = "livingTick",
at = @At(
value = "FIELD",
target = "net/minecraft/entity/player/PlayerCapabilities.allowFlying:Z"
@@ -105,7 +105,7 @@ public class MixinEntityPlayerSP {
}
@Redirect(
method = "onLivingUpdate",
method = "livingTick",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/settings/KeyBinding.isKeyDown()Z"

View File

@@ -20,24 +20,24 @@ package baritone.launch.mixins;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.event.events.RenderEvent;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.client.renderer.GameRenderer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(EntityRenderer.class)
public class MixinEntityRenderer {
@Mixin(GameRenderer.class)
public class MixinGameRenderer {
@Inject(
method = "renderWorldPass",
method = "updateCameraAndRender(FJ)V",
at = @At(
value = "INVOKE_STRING",
target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V",
args = {"ldc=hand"}
)
)
private void renderWorldPass(int pass, float partialTicks, long finishTimeNano, CallbackInfo ci) {
private void renderWorldPass(float partialTicks, long finishTimeNano, CallbackInfo ci) {
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
ibaritone.getGameEventHandler().onRenderPass(new RenderEvent(partialTicks));
}

View File

@@ -97,10 +97,10 @@ public class MixinMinecraft {
}
@Inject(
method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Ljava/lang/String;)V",
method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Lnet/minecraft/client/gui/GuiScreen;)V",
at = @At("HEAD")
)
private void preLoadWorld(WorldClient world, String loadingMessage, CallbackInfo ci) {
private void preLoadWorld(WorldClient world, GuiScreen loadingScreen, CallbackInfo ci) {
// If we're unloading the world but one doesn't exist, ignore it
if (this.world == null && world == null) {
return;
@@ -117,10 +117,10 @@ public class MixinMinecraft {
}
@Inject(
method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Ljava/lang/String;)V",
method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Lnet/minecraft/client/gui/GuiScreen;)V",
at = @At("RETURN")
)
private void postLoadWorld(WorldClient world, String loadingMessage, CallbackInfo ci) {
private void postLoadWorld(WorldClient world, GuiScreen loadingScreen, CallbackInfo ci) {
// still fire event for both null, as that means we've just finished exiting a world
// mc.world changing is only the primary baritone

View File

@@ -24,6 +24,7 @@ import baritone.api.event.events.type.EventState;
import net.minecraft.client.network.NetHandlerPlayClient;
import net.minecraft.network.play.server.SPacketChunkData;
import net.minecraft.network.play.server.SPacketCombatEvent;
import net.minecraft.network.play.server.SPacketUnloadChunk;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -40,7 +41,7 @@ public class MixinNetHandlerPlayClient {
method = "handleChunkData",
at = @At(
value = "INVOKE",
target = "net/minecraft/world/chunk/Chunk.read(Lnet/minecraft/network/PacketBuffer;IZ)V"
target = "net/minecraft/client/multiplayer/ChunkProviderClient.func_212474_a(IILnet/minecraft/network/PacketBuffer;IZ)Lnet/minecraft/world/chunk/Chunk;"
)
)
private void preRead(SPacketChunkData packetIn, CallbackInfo ci) {
@@ -77,6 +78,34 @@ public class MixinNetHandlerPlayClient {
}
}
@Inject(
method = "processChunkUnload",
at = @At("HEAD")
)
private void preChunkUnload(SPacketUnloadChunk packet, CallbackInfo ci) {
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
if (ibaritone.getPlayerContext().player().connection == (NetHandlerPlayClient) (Object) this) {
ibaritone.getGameEventHandler().onChunkEvent(
new ChunkEvent(EventState.PRE, ChunkEvent.Type.UNLOAD, packet.getX(), packet.getZ())
);
}
}
}
@Inject(
method = "processChunkUnload",
at = @At("RETURN")
)
private void postChunkUnload(SPacketUnloadChunk packet, CallbackInfo ci) {
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
if (ibaritone.getPlayerContext().player().connection == (NetHandlerPlayClient) (Object) this) {
ibaritone.getGameEventHandler().onChunkEvent(
new ChunkEvent(EventState.POST, ChunkEvent.Type.UNLOAD, packet.getX(), packet.getZ())
);
}
}
}
@Inject(
method = "handleCombatEvent",
at = @At(

View File

@@ -53,7 +53,7 @@ public class MixinNetworkManager {
method = "dispatchPacket",
at = @At("HEAD")
)
private void preDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>>[] futureListeners, CallbackInfo ci) {
private void preDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>> futureListeners, CallbackInfo ci) {
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
return;
}
@@ -69,7 +69,7 @@ public class MixinNetworkManager {
method = "dispatchPacket",
at = @At("RETURN")
)
private void postDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>>[] futureListeners, CallbackInfo ci) {
private void postDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>> futureListeners, CallbackInfo ci) {
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
return;
}
@@ -85,7 +85,7 @@ public class MixinNetworkManager {
method = "channelRead0",
at = @At(
value = "INVOKE",
target = "net/minecraft/network/Packet.processPacket(Lnet/minecraft/network/INetHandler;)V"
target = "net/minecraft/network/NetworkManager.processPacket(Lnet/minecraft/network/Packet;Lnet/minecraft/network/INetHandler;)V"
)
)
private void preProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {

View File

@@ -23,8 +23,8 @@ import baritone.api.utils.IPlayerContext;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.chunk.RenderChunk;
import net.minecraft.client.renderer.chunk.RenderChunkCache;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.ChunkCache;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@@ -40,43 +40,11 @@ public class MixinRenderChunk {
method = "rebuildChunk",
at = @At(
value = "INVOKE",
target = "net/minecraft/world/ChunkCache.isEmpty()Z"
target = "net/minecraft/client/renderer/chunk/RenderChunkCache.getBlockState(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/state/IBlockState;"
)
)
private boolean isEmpty(ChunkCache chunkCache) {
if (!chunkCache.isEmpty()) {
return false;
}
if (Baritone.settings().renderCachedChunks.value && Minecraft.getMinecraft().getIntegratedServer() == null) {
Baritone baritone = (Baritone) BaritoneAPI.getProvider().getPrimaryBaritone();
IPlayerContext ctx = baritone.getPlayerContext();
if (ctx.player() != null && ctx.world() != null && baritone.bsi != null) {
BlockPos position = ((RenderChunk) (Object) this).getPosition();
// RenderChunk extends from -1,-1,-1 to +16,+16,+16
// then the constructor of ChunkCache extends it one more (presumably to get things like the connected status of fences? idk)
// so if ANY of the adjacent chunks are loaded, we are unempty
for (int dx = -1; dx <= 1; dx++) {
for (int dz = -1; dz <= 1; dz++) {
if (baritone.bsi.isLoaded(16 * dx + position.getX(), 16 * dz + position.getZ())) {
return false;
}
}
}
}
}
return true;
}
@Redirect(
method = "rebuildChunk",
at = @At(
value = "INVOKE",
target = "net/minecraft/world/ChunkCache.getBlockState(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/state/IBlockState;"
)
)
private IBlockState getBlockState(ChunkCache chunkCache, BlockPos pos) {
if (Baritone.settings().renderCachedChunks.value && Minecraft.getMinecraft().getIntegratedServer() == null) {
private IBlockState getBlockState(RenderChunkCache chunkCache, BlockPos pos) {
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getInstance().isSingleplayer()) {
Baritone baritone = (Baritone) BaritoneAPI.getProvider().getPrimaryBaritone();
IPlayerContext ctx = baritone.getPlayerContext();
if (ctx.player() != null && ctx.world() != null && baritone.bsi != null) {

View File

@@ -0,0 +1,47 @@
/*
* 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.launch.mixins;
import baritone.Baritone;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.chunk.RenderChunkCache;
import net.minecraft.world.chunk.Chunk;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(RenderChunkCache.class)
public class MixinRenderChunkCache {
@Redirect(
method = "generateCache",
at = @At(
value = "INVOKE",
target = "net/minecraft/world/chunk/Chunk.isEmptyBetween(II)Z"
)
)
private static boolean isEmpty(Chunk chunk, int yStart, int yEnd) {
if (!chunk.isEmptyBetween(yStart, yEnd)) {
return false;
}
if (chunk.isEmpty() && Baritone.settings().renderCachedChunks.value && Minecraft.getInstance().getIntegratedServer() == null) {
return false;
}
return true;
}
}

View File

@@ -38,9 +38,9 @@ public class MixinRenderList {
)
)
private void popMatrix() {
if (Baritone.settings().renderCachedChunks.value && Minecraft.getMinecraft().getIntegratedServer() == null) {
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getInstance().isSingleplayer()) {
// reset the blend func to normal (not dependent on constant alpha)
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
GlStateManager.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
}
GlStateManager.popMatrix();
}

View File

@@ -38,9 +38,9 @@ public class MixinVboRenderList {
)
)
private void popMatrix() {
if (Baritone.settings().renderCachedChunks.value && Minecraft.getMinecraft().getIntegratedServer() == null) {
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getInstance().isSingleplayer()) {
// reset the blend func to normal (not dependent on constant alpha)
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
GlStateManager.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
}
GlStateManager.popMatrix();
}

View File

@@ -1,75 +0,0 @@
/*
* 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.launch.mixins;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.event.events.ChunkEvent;
import baritone.api.event.events.type.EventState;
import net.minecraft.client.multiplayer.WorldClient;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* @author Brady
* @since 8/2/2018
*/
@Mixin(WorldClient.class)
public class MixinWorldClient {
@Inject(
method = "doPreChunk",
at = @At("HEAD")
)
private void preDoPreChunk(int chunkX, int chunkZ, boolean loadChunk, CallbackInfo ci) {
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
if (ibaritone.getPlayerContext().world() == (WorldClient) (Object) this) {
ibaritone.getGameEventHandler().onChunkEvent(
new ChunkEvent(
EventState.PRE,
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
chunkX,
chunkZ
)
);
}
}
}
@Inject(
method = "doPreChunk",
at = @At("RETURN")
)
private void postDoPreChunk(int chunkX, int chunkZ, boolean loadChunk, CallbackInfo ci) {
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
if (ibaritone.getPlayerContext().world() == (WorldClient) (Object) this) {
ibaritone.getGameEventHandler().onChunkEvent(
new ChunkEvent(
EventState.POST,
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
chunkX,
chunkZ
)
);
}
}
}
}

View File

@@ -16,13 +16,13 @@
"MixinChunkRenderWorker",
"MixinEntityLivingBase",
"MixinEntityPlayerSP",
"MixinEntityRenderer",
"MixinGameRenderer",
"MixinMinecraft",
"MixinNetHandlerPlayClient",
"MixinNetworkManager",
"MixinRenderChunk",
"MixinRenderChunkCache",
"MixinRenderList",
"MixinVboRenderList",
"MixinWorldClient"
"MixinVboRenderList"
]
}

View File

@@ -21,6 +21,8 @@ import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.Settings;
import baritone.api.event.listener.IEventBus;
import baritone.api.utils.ExampleBaritoneControl;
import baritone.api.utils.Helper;
import baritone.api.utils.IPlayerContext;
import baritone.behavior.*;
import baritone.cache.WorldProvider;
@@ -33,8 +35,6 @@ import net.minecraft.client.Minecraft;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
@@ -52,7 +52,7 @@ public class Baritone implements IBaritone {
static {
threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
dir = new File(Minecraft.getMinecraft().gameDir, "baritone");
dir = new File(Minecraft.getInstance().gameDir, "baritone");
if (!Files.exists(dir.toPath())) {
try {
Files.createDirectories(dir.toPath());
@@ -67,7 +67,6 @@ public class Baritone implements IBaritone {
private GameEventHandler gameEventHandler;
private List<Behavior> behaviors;
private PathingBehavior pathingBehavior;
private LookBehavior lookBehavior;
private MemoryBehavior memoryBehavior;
@@ -80,6 +79,8 @@ public class Baritone implements IBaritone {
private CustomGoalProcess customGoalProcess;
private BuilderProcess builderProcess;
private ExploreProcess exploreProcess;
private BackfillProcess backfillProcess;
private FarmProcess farmProcess;
private PathingControlManager pathingControlManager;
@@ -101,7 +102,6 @@ public class Baritone implements IBaritone {
// Define this before behaviors try and get it, or else it will be null and the builds will fail!
this.playerContext = PrimaryPlayerContext.INSTANCE;
this.behaviors = new ArrayList<>();
{
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
pathingBehavior = new PathingBehavior(this);
@@ -120,6 +120,8 @@ public class Baritone implements IBaritone {
getToBlockProcess = new GetToBlockProcess(this);
builderProcess = new BuilderProcess(this);
exploreProcess = new ExploreProcess(this);
backfillProcess = new BackfillProcess(this);
farmProcess = new FarmProcess(this);
}
this.worldProvider = new WorldProvider();
@@ -136,12 +138,7 @@ public class Baritone implements IBaritone {
return this.pathingControlManager;
}
public List<Behavior> getBehaviors() {
return this.behaviors;
}
public void registerBehavior(Behavior behavior) {
this.behaviors.add(behavior);
this.gameEventHandler.registerEventListener(behavior);
}
@@ -197,6 +194,10 @@ public class Baritone implements IBaritone {
return this.mineProcess;
}
public FarmProcess getFarmProcess() {
return this.farmProcess;
}
@Override
public PathingBehavior getPathingBehavior() {
return this.pathingBehavior;
@@ -212,6 +213,16 @@ public class Baritone implements IBaritone {
return this.gameEventHandler;
}
@Override
public void openClick() {
new Thread(() -> {
try {
Thread.sleep(100);
Helper.mc.addScheduledTask(() -> Helper.mc.displayGuiScreen(new GuiClick()));
} catch (Exception ignored) {}
}).start();
}
public static Settings settings() {
return BaritoneAPI.getSettings();
}

View File

@@ -32,6 +32,7 @@ import java.util.List;
public final class BaritoneProvider implements IBaritoneProvider {
private final Baritone primary = new Baritone();
private final List<IBaritone> all = Collections.singletonList(primary);
@Override
public IBaritone getPrimaryBaritone() {
@@ -40,8 +41,7 @@ public final class BaritoneProvider implements IBaritoneProvider {
@Override
public List<IBaritone> getAllBaritones() {
// TODO return a CopyOnWriteArrayList
return Collections.singletonList(primary);
return all;
}
@Override

View File

@@ -33,7 +33,7 @@ import java.util.OptionalInt;
import java.util.Random;
import java.util.function.Predicate;
public class InventoryBehavior extends Behavior {
public final class InventoryBehavior extends Behavior {
public InventoryBehavior(Baritone baritone) {
super(baritone);
}
@@ -123,27 +123,27 @@ public class InventoryBehavior extends Behavior {
public boolean hasGenericThrowaway() {
for (Item item : Baritone.settings().acceptableThrowawayItems.value) {
if (throwaway(false, item::equals)) {
if (throwaway(false, stack -> item.equals(stack.getItem()))) {
return true;
}
}
return false;
}
public boolean selectThrowawayForLocation(int x, int y, int z) {
public boolean selectThrowawayForLocation(boolean select, int x, int y, int z) {
IBlockState maybe = baritone.getBuilderProcess().placeAt(x, y, z);
if (maybe != null && throwaway(true, item -> item instanceof ItemBlock && ((ItemBlock) item).getBlock().equals(maybe.getBlock()))) {
if (maybe != null && throwaway(select, stack -> stack.getItem() instanceof ItemBlock && ((ItemBlock) stack.getItem()).getBlock().equals(maybe.getBlock()))) {
return true; // gotem
}
for (Item item : Baritone.settings().acceptableThrowawayItems.value) {
if (throwaway(true, item::equals)) {
if (throwaway(select, stack -> item.equals(stack.getItem()))) {
return true;
}
}
return false;
}
private boolean throwaway(boolean select, Predicate<? super Item> desired) {
public boolean throwaway(boolean select, Predicate<? super ItemStack> desired) {
EntityPlayerSP p = ctx.player();
NonNullList<ItemStack> inv = p.inventory.mainInventory;
for (byte i = 0; i < 9; i++) {
@@ -153,14 +153,14 @@ public class InventoryBehavior extends Behavior {
// and then it's called during execution
// since this function is never called during cost calculation, we don't need to migrate
// acceptableThrowawayItems to the CalculationContext
if (desired.test(item.getItem())) {
if (desired.test(item)) {
if (select) {
p.inventory.currentItem = i;
}
return true;
}
}
if (desired.test(p.inventory.offHandInventory.get(0).getItem())) {
if (desired.test(p.inventory.offHandInventory.get(0))) {
// main hand takes precedence over off hand
// that means that if we have block A selected in main hand and block B in off hand, right clicking places block B
// we've already checked above ^ and the main hand can't possible have an acceptablethrowawayitem

View File

@@ -28,9 +28,6 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
/**
* Target's values are as follows:
* <p>
* getFirst() -> yaw
* getSecond() -> pitch
*/
private Rotation target;
@@ -53,6 +50,13 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
@Override
public void updateTarget(Rotation target, boolean force) {
this.target = target;
if (!force) {
double rand = Math.random() - 0.5;
if (Math.abs(rand) < 0.1) {
rand *= 4;
}
this.target = new Rotation(this.target.getYaw() + (float) (rand * Baritone.settings().randomLooking.value), this.target.getPitch());
}
this.force = force || !Baritone.settings().freeLook.value;
}
@@ -72,8 +76,8 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
float oldPitch = ctx.player().rotationPitch;
float desiredPitch = this.target.getPitch();
ctx.player().rotationPitch = desiredPitch;
if (desiredPitch == oldPitch) {
//nudgeToLevel();
if (desiredPitch == oldPitch && !Baritone.settings().freeLook.value) {
nudgeToLevel();
}
this.target = null;
}

View File

@@ -18,13 +18,13 @@
package baritone.behavior;
import baritone.Baritone;
import baritone.api.cache.Waypoint;
import baritone.api.event.events.BlockInteractEvent;
import baritone.api.event.events.PacketEvent;
import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.TickEvent;
import baritone.api.event.events.type.EventState;
import baritone.cache.ContainerMemory;
import baritone.cache.Waypoint;
import baritone.utils.BlockStateInterface;
import net.minecraft.block.Block;
import net.minecraft.block.BlockBed;

View File

@@ -25,6 +25,7 @@ import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalXZ;
import baritone.api.process.PathingCommand;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Helper;
import baritone.api.utils.PathCalculationResult;
import baritone.api.utils.interfaces.IGoalRenderPos;
import baritone.pathing.calc.AStarPathFinder;
@@ -32,7 +33,6 @@ import baritone.pathing.calc.AbstractNodeCostSearch;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.path.PathExecutor;
import baritone.utils.Helper;
import baritone.utils.PathRenderer;
import baritone.utils.PathingCommandContext;
import baritone.utils.pathing.Favoring;
@@ -65,7 +65,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
private boolean lastAutoJump;
private BlockPos expectedSegmentStart;
private BetterBlockPos expectedSegmentStart;
private final LinkedBlockingQueue<PathEvent> toDispatch = new LinkedBlockingQueue<>();
@@ -195,7 +195,9 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
current.onTick();
return;
}
current = current.trySplice(next);
if (Baritone.settings().splicePath.value) {
current = current.trySplice(next);
}
if (next != null && current.getPath().getDest().equals(next.getPath().getDest())) {
next = null;
}
@@ -350,7 +352,8 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
}
}
public void forceCancel() { // NOT exposed on public api
@Override
public void forceCancel() { // exposed on public api because :sob:
cancelEverything();
secretInternalSegmentCancel();
synchronized (pathCalcLock) {
@@ -358,11 +361,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
}
}
public void secretCursedFunctionDoNotCall(IPath path) {
/*public void secretCursedFunctionDoNotCall(IPath path) {
synchronized (pathPlanLock) {
current = new PathExecutor(this, path);
}
}
}*/
public CalculationContext secretInternalGetCalculationContext() {
return context;

View File

@@ -17,14 +17,19 @@
package baritone.cache;
import baritone.api.utils.BlockUtils;
import baritone.utils.pathing.PathingBlockType;
import com.google.common.collect.ImmutableSet;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import java.util.*;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
import java.util.Map;
/**
* @author Brady
@@ -32,64 +37,77 @@ import java.util.*;
*/
public final class CachedChunk {
public static final Set<Block> BLOCKS_TO_KEEP_TRACK_OF;
public static final ImmutableSet<Block> BLOCKS_TO_KEEP_TRACK_OF = ImmutableSet.of(
Blocks.ENDER_CHEST,
Blocks.FURNACE,
Blocks.CHEST,
Blocks.TRAPPED_CHEST,
Blocks.END_PORTAL,
Blocks.END_PORTAL_FRAME,
Blocks.SPAWNER,
Blocks.BARRIER,
Blocks.OBSERVER,
Blocks.WHITE_SHULKER_BOX,
Blocks.ORANGE_SHULKER_BOX,
Blocks.MAGENTA_SHULKER_BOX,
Blocks.LIGHT_BLUE_SHULKER_BOX,
Blocks.YELLOW_SHULKER_BOX,
Blocks.LIME_SHULKER_BOX,
Blocks.PINK_SHULKER_BOX,
Blocks.GRAY_SHULKER_BOX,
Blocks.LIGHT_GRAY_SHULKER_BOX,
Blocks.CYAN_SHULKER_BOX,
Blocks.PURPLE_SHULKER_BOX,
Blocks.BLUE_SHULKER_BOX,
Blocks.BROWN_SHULKER_BOX,
Blocks.GREEN_SHULKER_BOX,
Blocks.RED_SHULKER_BOX,
Blocks.BLACK_SHULKER_BOX,
Blocks.NETHER_PORTAL,
Blocks.HOPPER,
Blocks.BEACON,
Blocks.BREWING_STAND,
static {
HashSet<Block> temp = new HashSet<>();
//temp.add(Blocks.DIAMOND_ORE);
temp.add(Blocks.DIAMOND_BLOCK);
//temp.add(Blocks.COAL_ORE);
temp.add(Blocks.COAL_BLOCK);
//temp.add(Blocks.IRON_ORE);
temp.add(Blocks.IRON_BLOCK);
//temp.add(Blocks.GOLD_ORE);
temp.add(Blocks.GOLD_BLOCK);
temp.add(Blocks.EMERALD_ORE);
temp.add(Blocks.EMERALD_BLOCK);
temp.add(Blocks.ENDER_CHEST);
temp.add(Blocks.FURNACE);
temp.add(Blocks.CHEST);
temp.add(Blocks.TRAPPED_CHEST);
temp.add(Blocks.END_PORTAL);
temp.add(Blocks.END_PORTAL_FRAME);
temp.add(Blocks.MOB_SPAWNER);
temp.add(Blocks.BARRIER);
temp.add(Blocks.OBSERVER);
temp.add(Blocks.WHITE_SHULKER_BOX);
temp.add(Blocks.ORANGE_SHULKER_BOX);
temp.add(Blocks.MAGENTA_SHULKER_BOX);
temp.add(Blocks.LIGHT_BLUE_SHULKER_BOX);
temp.add(Blocks.YELLOW_SHULKER_BOX);
temp.add(Blocks.LIME_SHULKER_BOX);
temp.add(Blocks.PINK_SHULKER_BOX);
temp.add(Blocks.GRAY_SHULKER_BOX);
temp.add(Blocks.SILVER_SHULKER_BOX);
temp.add(Blocks.CYAN_SHULKER_BOX);
temp.add(Blocks.PURPLE_SHULKER_BOX);
temp.add(Blocks.BLUE_SHULKER_BOX);
temp.add(Blocks.BROWN_SHULKER_BOX);
temp.add(Blocks.GREEN_SHULKER_BOX);
temp.add(Blocks.RED_SHULKER_BOX);
temp.add(Blocks.BLACK_SHULKER_BOX);
temp.add(Blocks.PORTAL);
temp.add(Blocks.HOPPER);
temp.add(Blocks.BEACON);
temp.add(Blocks.BREWING_STAND);
temp.add(Blocks.SKULL);
temp.add(Blocks.ENCHANTING_TABLE);
temp.add(Blocks.ANVIL);
temp.add(Blocks.LIT_FURNACE);
temp.add(Blocks.BED);
temp.add(Blocks.DRAGON_EGG);
temp.add(Blocks.JUKEBOX);
temp.add(Blocks.END_GATEWAY);
temp.add(Blocks.WEB);
temp.add(Blocks.NETHER_WART);
temp.add(Blocks.LADDER);
temp.add(Blocks.VINE);
BLOCKS_TO_KEEP_TRACK_OF = Collections.unmodifiableSet(temp);
}
// TODO: Maybe add a predicate for blocks to keep track of?
// This should really not need to happen
Blocks.CREEPER_HEAD,
Blocks.CREEPER_WALL_HEAD,
Blocks.DRAGON_HEAD,
Blocks.DRAGON_WALL_HEAD,
Blocks.PLAYER_HEAD,
Blocks.PLAYER_WALL_HEAD,
Blocks.ZOMBIE_HEAD,
Blocks.ZOMBIE_WALL_HEAD,
Blocks.SKELETON_SKULL,
Blocks.SKELETON_WALL_SKULL,
Blocks.WITHER_SKELETON_SKULL,
Blocks.WITHER_SKELETON_WALL_SKULL,
Blocks.ENCHANTING_TABLE,
Blocks.ANVIL,
Blocks.WHITE_BED,
Blocks.ORANGE_BED,
Blocks.MAGENTA_BED,
Blocks.LIGHT_BLUE_BED,
Blocks.YELLOW_BED,
Blocks.LIME_BED,
Blocks.PINK_BED,
Blocks.GRAY_BED,
Blocks.LIGHT_GRAY_BED,
Blocks.CYAN_BED,
Blocks.PURPLE_BED,
Blocks.BLUE_BED,
Blocks.BROWN_BED,
Blocks.GREEN_BED,
Blocks.RED_BED,
Blocks.BLACK_BED,
Blocks.DRAGON_EGG,
Blocks.JUKEBOX,
Blocks.END_GATEWAY,
Blocks.COBWEB,
Blocks.NETHER_WART,
Blocks.LADDER,
Blocks.VINE
);
/**
* The size of the chunk data in bits. Equal to 16 KiB.
@@ -169,15 +187,15 @@ public final class CachedChunk {
// we have this exact block, it's a surface block
/*System.out.println("Saying that " + x + "," + y + "," + z + " is " + state);
if (!Minecraft.getMinecraft().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock().equals(state.getBlock())) {
throw new IllegalStateException("failed " + Minecraft.getMinecraft().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock() + " " + state.getBlock() + " " + (x + this.x * 16) + " " + y + " " + (z + this.z * 16));
if (!Minecraft.getInstance().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock().equals(state.getBlock())) {
throw new IllegalStateException("failed " + Minecraft.getInstance().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock() + " " + state.getBlock() + " " + (x + this.x * 16) + " " + y + " " + (z + this.z * 16));
}*/
return overview[internalPos];
}
if (special != null) {
String str = special.get(index);
if (str != null) {
return ChunkPacker.stringToBlockRequired(str).getDefaultState();
return BlockUtils.stringToBlockRequired(str).getDefaultState();
}
}

View File

@@ -19,6 +19,7 @@ package baritone.cache;
import baritone.Baritone;
import baritone.api.cache.ICachedRegion;
import baritone.api.utils.BlockUtils;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.BlockPos;
@@ -149,7 +150,7 @@ public final class CachedRegion implements ICachedRegion {
for (int z = 0; z < 32; z++) {
if (chunks[x][z] != null) {
for (int i = 0; i < 256; i++) {
out.writeUTF(ChunkPacker.blockToString(chunks[x][z].getOverview()[i].getBlock()));
out.writeUTF(BlockUtils.blockToString(chunks[x][z].getOverview()[i].getBlock()));
}
}
}
@@ -240,7 +241,7 @@ public final class CachedRegion implements ICachedRegion {
for (int z = 0; z < 32; z++) {
if (present[x][z]) {
for (int i = 0; i < 256; i++) {
overview[x][z][i] = ChunkPacker.stringToBlockRequired(in.readUTF()).getDefaultState();
overview[x][z][i] = BlockUtils.stringToBlockRequired(in.readUTF()).getDefaultState();
}
}
}
@@ -255,7 +256,7 @@ public final class CachedRegion implements ICachedRegion {
int numSpecialBlockTypes = in.readShort() & 0xffff;
for (int i = 0; i < numSpecialBlockTypes; i++) {
String blockName = in.readUTF();
ChunkPacker.stringToBlockRequired(blockName);
BlockUtils.stringToBlockRequired(blockName);
List<BlockPos> locs = new ArrayList<>();
location[x][z].put(blockName, locs);
int numLocations = in.readShort() & 0xffff;

View File

@@ -22,7 +22,7 @@ import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.cache.ICachedWorld;
import baritone.api.cache.IWorldData;
import baritone.utils.Helper;
import baritone.api.utils.Helper;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.minecraft.util.math.BlockPos;
@@ -180,8 +180,8 @@ public final class CachedWorld implements ICachedWorld, Helper {
if (region == null) {
continue;
}
int distX = (region.getX() << 9 + 256) - pruneCenter.getX();
int distZ = (region.getZ() << 9 + 256) - pruneCenter.getZ();
int distX = ((region.getX() << 9) + 256) - pruneCenter.getX();
int distZ = ((region.getZ() << 9) + 256) - pruneCenter.getZ();
double dist = Math.sqrt(distX * distX + distZ * distZ);
if (dist > 1024) {
logDebug("Deleting cached region " + region.getX() + "," + region.getZ() + " from ram");
@@ -216,7 +216,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
if (mostRecentlyModified == null) {
return new BlockPos(0, 0, 0);
}
return new BlockPos(mostRecentlyModified.x << 4 + 8, 0, mostRecentlyModified.z << 4 + 8);
return new BlockPos((mostRecentlyModified.x << 4) + 8, 0, (mostRecentlyModified.z << 4) + 8);
}
private synchronized List<CachedRegion> allRegions() {
@@ -303,6 +303,9 @@ public final class CachedWorld implements ICachedWorld, Helper {
} catch (InterruptedException e) {
e.printStackTrace();
break;
} catch (Throwable th) {
// in the case of an exception, keep consuming from the queue so as not to leak memory
th.printStackTrace();
}
}
}

View File

@@ -17,16 +17,17 @@
package baritone.cache;
import baritone.api.utils.BlockUtils;
import baritone.pathing.movement.MovementHelper;
import baritone.utils.pathing.PathingBlockType;
import net.minecraft.block.*;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.chunk.BlockStateContainer;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import net.minecraft.world.chunk.ChunkSection;
import java.util.*;
@@ -36,8 +37,6 @@ import java.util.*;
*/
public final class ChunkPacker {
private static final Map<String, Block> resourceCache = new HashMap<>();
private ChunkPacker() {}
public static CachedChunk pack(Chunk chunk) {
@@ -46,9 +45,9 @@ public final class ChunkPacker {
Map<String, List<BlockPos>> specialBlocks = new HashMap<>();
BitSet bitSet = new BitSet(CachedChunk.SIZE);
try {
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
ChunkSection[] chunkInternalStorageArray = chunk.getSections();
for (int y0 = 0; y0 < 16; y0++) {
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
ChunkSection extendedblockstorage = chunkInternalStorageArray[y0];
if (extendedblockstorage == null) {
// any 16x16x16 area that's all air will have null storage
// for example, in an ocean biome, with air from y=64 to y=256
@@ -60,7 +59,7 @@ public final class ChunkPacker {
// since a bitset is initialized to all zero, and air is saved as zeros
continue;
}
BlockStateContainer bsc = extendedblockstorage.getData();
BlockStateContainer<IBlockState> bsc = extendedblockstorage.getData();
int yReal = y0 << 4;
// the mapping of BlockStateContainer.getIndex from xyz to index is y << 8 | z << 4 | x;
// for better cache locality, iterate in that order
@@ -75,7 +74,7 @@ public final class ChunkPacker {
bitSet.set(index + 1, bits[1]);
Block block = state.getBlock();
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(block)) {
String name = blockToString(block);
String name = BlockUtils.blockToString(block);
specialBlocks.computeIfAbsent(name, b -> new ArrayList<>()).add(new BlockPos(x, y, z));
}
}
@@ -105,54 +104,40 @@ public final class ChunkPacker {
return new CachedChunk(chunk.x, chunk.z, bitSet, blocks, specialBlocks, System.currentTimeMillis());
}
public static String blockToString(Block block) {
ResourceLocation loc = Block.REGISTRY.getNameForObject(block);
String name = loc.getPath(); // normally, only write the part after the minecraft:
if (!loc.getNamespace().equals("minecraft")) {
// Baritone is running on top of forge with mods installed, perhaps?
name = loc.toString(); // include the namespace with the colon
}
return name;
}
public static Block stringToBlockRequired(String name) {
Block block = stringToBlockNullable(name);
Objects.requireNonNull(block);
return block;
}
public static Block stringToBlockNullable(String name) {
return resourceCache.computeIfAbsent(name, n -> Block.getBlockFromName(n.contains(":") ? n : "minecraft:" + n));
}
private static PathingBlockType getPathingBlockType(IBlockState state, Chunk chunk, int x, int y, int z) {
Block block = state.getBlock();
if (block == Blocks.WATER || block == Blocks.FLOWING_WATER) {
if (MovementHelper.isWater(state)) {
// only water source blocks are plausibly usable, flowing water should be avoid
// FLOWING_WATER is a waterfall, it doesn't really matter and caching it as AVOID just makes it look wrong
if (MovementHelper.possiblyFlowing(state)) {
return PathingBlockType.AVOID;
}
if (x == 0 || x == 15 || z == 0 || z == 15) {
if (BlockLiquid.getSlopeAngle(chunk.getWorld(), new BlockPos(x + chunk.x << 4, y, z + chunk.z << 4), state.getMaterial(), state) == -1000.0F) {
return PathingBlockType.WATER;
}
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 (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))) {
if (x == 0 || x == 15 || z == 0 || z == 15) {
Vec3d flow = state.getFluidState().getFlow(chunk.getWorld(), new BlockPos(x + chunk.x << 4, y, z + chunk.z << 4));
if (flow.x != 0.0 || flow.z != 0.0) {
return PathingBlockType.WATER;
}
return PathingBlockType.AVOID;
}
return PathingBlockType.WATER;
}
if (MovementHelper.avoidWalkingInto(block) || MovementHelper.isBottomSlab(state)) {
if (MovementHelper.avoidWalkingInto(state) || MovementHelper.isBottomSlab(state)) {
return PathingBlockType.AVOID;
}
// We used to do an AABB check here
// however, this failed in the nether when you were near a nether fortress
// because fences check their adjacent blocks in the world for their fence connection status to determine AABB shape
// this caused a nullpointerexception when we saved chunks on unload, because they were unable to check their neighbors
if (block == Blocks.AIR || block instanceof BlockTallGrass || block instanceof BlockDoublePlant || block instanceof BlockFlower) {
if (block instanceof BlockAir || block instanceof BlockTallGrass || block instanceof BlockDoublePlant || block instanceof BlockFlower) {
return PathingBlockType.AIR;
}

View File

@@ -29,6 +29,7 @@ import net.minecraft.util.math.BlockPos;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.*;
@@ -45,6 +46,8 @@ public class ContainerMemory implements IContainerMemory {
this.saveTo = saveTo;
try {
read(Files.readAllBytes(saveTo));
} catch (NoSuchFileException ignored) {
inventories.clear();
} catch (Exception ex) {
ex.printStackTrace();
inventories.clear();

View File

@@ -19,6 +19,7 @@ package baritone.cache;
import baritone.api.cache.IWaypoint;
import baritone.api.cache.IWaypointCollection;
import baritone.api.cache.Waypoint;
import net.minecraft.util.math.BlockPos;
import java.io.*;

View File

@@ -19,11 +19,12 @@ package baritone.cache;
import baritone.Baritone;
import baritone.api.cache.IWorldProvider;
import baritone.utils.Helper;
import baritone.api.utils.Helper;
import baritone.utils.accessor.IAnvilChunkLoader;
import baritone.utils.accessor.IChunkProviderServer;
import net.minecraft.server.integrated.IntegratedServer;
import net.minecraft.world.WorldServer;
import net.minecraft.world.dimension.DimensionType;
import org.apache.commons.lang3.SystemUtils;
import java.io.File;
@@ -55,14 +56,14 @@ public class WorldProvider implements IWorldProvider, Helper {
*
* @param dimension The ID of the world's dimension
*/
public final void initWorld(int dimension) {
public final void initWorld(DimensionType dimension) {
File directory;
File readme;
IntegratedServer integratedServer = mc.getIntegratedServer();
// If there is an integrated server running (Aka Singleplayer) then do magic to find the world save file
if (integratedServer != null) {
if (mc.isSingleplayer()) {
WorldServer localServerWorld = integratedServer.getWorld(dimension);
IChunkProviderServer provider = (IChunkProviderServer) localServerWorld.getChunkProvider();
IAnvilChunkLoader loader = (IAnvilChunkLoader) provider.getChunkLoader();
@@ -92,7 +93,7 @@ public class WorldProvider implements IWorldProvider, Helper {
} catch (IOException ignored) {}
// We will actually store the world data in a subfolder: "DIM<id>"
Path dir = new File(directory, "DIM" + dimension).toPath();
Path dir = new File(directory, "DIM" + dimension.getId()).toPath();
if (!Files.exists(dir)) {
try {
Files.createDirectories(dir);
@@ -101,7 +102,7 @@ public class WorldProvider implements IWorldProvider, Helper {
System.out.println("Baritone world data dir: " + dir);
synchronized (worldCache) {
this.currentWorld = worldCache.computeIfAbsent(dir, d -> new WorldData(d, dimension));
this.currentWorld = worldCache.computeIfAbsent(dir, d -> new WorldData(d, dimension.getId()));
}
}

View File

@@ -26,17 +26,17 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.chunk.BlockStateContainer;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import net.minecraft.world.chunk.ChunkSection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.*;
import java.util.stream.IntStream;
public enum WorldScanner implements IWorldScanner {
INSTANCE;
private static final int[] DEFAULT_COORDINATE_ITERATION_ORDER = IntStream.range(0, 16).toArray();
@Override
public List<BlockPos> scanChunkRadius(IPlayerContext ctx, List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius) {
if (blocks.contains(null)) {
@@ -53,6 +53,9 @@ public enum WorldScanner implements IWorldScanner {
int playerChunkZ = ctx.playerFeet().getZ() >> 4;
int playerY = ctx.playerFeet().getY();
int playerYBlockStateContainerIndex = playerY >> 4;
int[] coordinateIterationOrder = IntStream.range(0, 16).boxed().sorted(Comparator.comparingInt(y -> Math.abs(y - playerYBlockStateContainerIndex))).mapToInt(x -> x).toArray();
int searchRadiusSq = 0;
boolean foundWithinY = false;
while (true) {
@@ -67,12 +70,14 @@ public enum WorldScanner implements IWorldScanner {
foundChunks = true;
int chunkX = xoff + playerChunkX;
int chunkZ = zoff + playerChunkZ;
Chunk chunk = chunkProvider.getLoadedChunk(chunkX, chunkZ);
Chunk chunk = chunkProvider.getChunk(chunkX, chunkZ, false, false);
if (chunk == null) {
continue;
}
allUnloaded = false;
scanChunkInto(chunkX << 4, chunkZ << 4, chunk, blocks, res, max, yLevelThreshold, playerY);
if (scanChunkInto(chunkX << 4, chunkZ << 4, chunk, blocks, res, max, yLevelThreshold, playerY, coordinateIterationOrder)) {
foundWithinY = true;
}
}
}
if ((allUnloaded && foundChunks)
@@ -92,7 +97,7 @@ public enum WorldScanner implements IWorldScanner {
}
ChunkProviderClient chunkProvider = (ChunkProviderClient) ctx.world().getChunkProvider();
Chunk chunk = chunkProvider.getLoadedChunk(pos.x, pos.z);
Chunk chunk = chunkProvider.getChunk(pos.x, pos.z, false, false);
int playerY = ctx.playerFeet().getY();
if (chunk == null || chunk.isEmpty()) {
@@ -100,19 +105,21 @@ public enum WorldScanner implements IWorldScanner {
}
ArrayList<BlockPos> res = new ArrayList<>();
scanChunkInto(pos.x << 4, pos.z << 4, chunk, blocks, res, max, yLevelThreshold, playerY);
scanChunkInto(pos.x << 4, pos.z << 4, chunk, blocks, res, max, yLevelThreshold, playerY, DEFAULT_COORDINATE_ITERATION_ORDER);
return res;
}
public void scanChunkInto(int chunkX, int chunkZ, Chunk chunk, List<Block> search, Collection<BlockPos> result, int max, int yLevelThreshold, int playerY) {
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
for (int y0 = 0; y0 < 16; y0++) {
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
private boolean scanChunkInto(int chunkX, int chunkZ, Chunk chunk, List<Block> search, Collection<BlockPos> result, int max, int yLevelThreshold, int playerY, int[] coordinateIterationOrder) {
ChunkSection[] chunkInternalStorageArray = chunk.getSections();
boolean foundWithinY = false;
for (int yIndex = 0; yIndex < 16; yIndex++) {
int y0 = coordinateIterationOrder[yIndex];
ChunkSection extendedblockstorage = chunkInternalStorageArray[y0];
if (extendedblockstorage == null) {
continue;
}
int yReal = y0 << 4;
BlockStateContainer bsc = extendedblockstorage.getData();
BlockStateContainer<IBlockState> bsc = extendedblockstorage.getData();
// the mapping of BlockStateContainer.getIndex from xyz to index is y << 8 | z << 4 | x;
// for better cache locality, iterate in that order
for (int y = 0; y < 16; y++) {
@@ -121,14 +128,23 @@ public enum WorldScanner implements IWorldScanner {
IBlockState state = bsc.get(x, y, z);
if (search.contains(state.getBlock())) {
int yy = yReal | y;
result.add(new BlockPos(chunkX | x, yy, chunkZ | z));
if (result.size() >= max && Math.abs(yy - playerY) < yLevelThreshold) {
return;
if (result.size() >= max) {
if (Math.abs(yy - playerY) < yLevelThreshold) {
foundWithinY = true;
} else {
if (foundWithinY) {
// have found within Y in this chunk, so don't need to consider outside Y
// TODO continue iteration to one more sorted Y coordinate block
return true;
}
}
}
result.add(new BlockPos(chunkX | x, yy, chunkZ | z));
}
}
}
}
}
return foundWithinY;
}
}

View File

@@ -22,9 +22,9 @@ import baritone.api.event.events.*;
import baritone.api.event.events.type.EventState;
import baritone.api.event.listener.IEventBus;
import baritone.api.event.listener.IGameEventListener;
import baritone.api.utils.Helper;
import baritone.cache.WorldProvider;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
@@ -84,7 +84,7 @@ public final class GameEventHandler implements IEventBus, Helper {
// to make sure the chunk being unloaded is already loaded.
boolean isPreUnload = state == EventState.PRE
&& type == ChunkEvent.Type.UNLOAD
&& world.getChunkProvider().isChunkGeneratedAt(event.getX(), event.getZ());
&& world.getChunkProvider().getChunk(event.getX(), event.getZ(), false, false) != null;
if (isPostPopulate || isPreUnload) {
baritone.getWorldProvider().ifWorldLoaded(worldData -> {
@@ -109,7 +109,7 @@ public final class GameEventHandler implements IEventBus, Helper {
if (event.getState() == EventState.POST) {
cache.closeWorld();
if (event.getWorld() != null) {
cache.initWorld(event.getWorld().provider.getDimensionType().getId());
cache.initWorld(event.getWorld().getDimension().getType());
}
}

View File

@@ -86,8 +86,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch {
if (slowPath) {
try {
Thread.sleep(Baritone.settings().slowPathTimeDelayMS.value);
} catch (InterruptedException ex) {
}
} catch (InterruptedException ignored) {}
}
PathNode currentNode = openSet.removeLowest();
mostRecentConsidered = currentNode;

View File

@@ -22,9 +22,9 @@ import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.calc.IPathFinder;
import baritone.api.pathing.goals.Goal;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Helper;
import baritone.api.utils.PathCalculationResult;
import baritone.pathing.movement.CalculationContext;
import baritone.utils.Helper;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import java.util.Optional;
@@ -186,7 +186,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder, Helper {
}
protected Optional<IPath> bestSoFar(boolean logInfo, int numNodes) {
if (startNode == null || bestSoFar == null) {
if (startNode == null) {
return Optional.empty();
}
double bestDist = 0;

View File

@@ -21,11 +21,11 @@ import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.movement.IMovement;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Helper;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.Moves;
import baritone.pathing.path.CutoffPath;
import baritone.utils.Helper;
import baritone.utils.pathing.PathBase;
import java.util.ArrayList;
@@ -96,7 +96,7 @@ class Path extends PathBase {
}
PathNode current = end;
LinkedList<BetterBlockPos> tempPath = new LinkedList<>();
LinkedList<PathNode> tempNodes = new LinkedList();
LinkedList<PathNode> tempNodes = new LinkedList<>();
// Repeatedly inserting to the beginning of an arraylist is O(n^2)
// Instead, do it into a linked list, then convert at the end
while (current != null) {

View File

@@ -60,6 +60,7 @@ public class CalculationContext {
public final boolean allowJumpAt256;
public final boolean assumeWalkOnWater;
public final boolean allowDiagonalDescend;
public final boolean allowDownward;
public final int maxFallHeightNoWater;
public final int maxFallHeightBucket;
public final double waterWalkSpeed;
@@ -82,7 +83,7 @@ public class CalculationContext {
this.bsi = new BlockStateInterface(world, worldData, forUseOnAnotherThread);
this.toolSet = new ToolSet(player);
this.hasThrowaway = Baritone.settings().allowPlace.value && ((Baritone) baritone).getInventoryBehavior().hasGenericThrowaway();
this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.value && InventoryPlayer.isHotbar(player.inventory.getSlotFor(STACK_BUCKET_WATER)) && !world.provider.isNether();
this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.value && InventoryPlayer.isHotbar(player.inventory.getSlotFor(STACK_BUCKET_WATER)) && !world.getDimension().isNether();
this.canSprint = Baritone.settings().allowSprint.value && player.getFoodStats().getFoodLevel() > 6;
this.placeBlockCost = Baritone.settings().blockPlacementPenalty.value;
this.allowBreak = Baritone.settings().allowBreak.value;
@@ -91,6 +92,7 @@ public class CalculationContext {
this.allowJumpAt256 = Baritone.settings().allowJumpAt256.value;
this.assumeWalkOnWater = Baritone.settings().assumeWalkOnWater.value;
this.allowDiagonalDescend = Baritone.settings().allowDiagonalDescend.value;
this.allowDownward = Baritone.settings().allowDownward.value;
this.maxFallHeightNoWater = Baritone.settings().maxFallHeightNoWater.value;
this.maxFallHeightBucket = Baritone.settings().maxFallHeightBucket.value;
int depth = EnchantmentHelper.getDepthStriderModifier(player);

View File

@@ -17,24 +17,24 @@
package baritone.pathing.movement;
import baritone.Baritone;
import baritone.api.IBaritone;
import baritone.api.pathing.movement.IMovement;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.*;
import baritone.api.utils.input.Input;
import baritone.behavior.PathingBehavior;
import baritone.utils.BlockStateInterface;
import net.minecraft.block.BlockLiquid;
import net.minecraft.entity.item.EntityFallingBlock;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.*;
public abstract class Movement implements IMovement, MovementHelper {
public static final EnumFacing[] HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP = {EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST, EnumFacing.DOWN};
public static final EnumFacing[] HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP = {EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST, EnumFacing.DOWN};
protected final IBaritone baritone;
protected final IPlayerContext ctx;
@@ -61,6 +61,8 @@ public abstract class Movement implements IMovement, MovementHelper {
public List<BlockPos> toPlaceCached = null;
public List<BlockPos> toWalkIntoCached = null;
private Set<BetterBlockPos> validPositionsCached = null;
private Boolean calculatedWhileLoaded;
protected Movement(IBaritone baritone, BetterBlockPos src, BetterBlockPos dest, BetterBlockPos[] toBreak, BetterBlockPos toPlace) {
@@ -98,6 +100,20 @@ public abstract class Movement implements IMovement, MovementHelper {
this.cost = cost;
}
protected abstract Set<BetterBlockPos> calculateValidPositions();
public Set<BetterBlockPos> getValidPositions() {
if (validPositionsCached == null) {
validPositionsCached = calculateValidPositions();
Objects.requireNonNull(validPositionsCached);
}
return validPositionsCached;
}
protected boolean playerInValidPosition() {
return getValidPositions().contains(ctx.playerFeet()) || getValidPositions().contains(((PathingBehavior) baritone.getPathingBehavior()).pathStart());
}
/**
* Handles the execution of the latest Movement
* State, and offers a Status to the calling class.
@@ -106,12 +122,13 @@ public abstract class Movement implements IMovement, MovementHelper {
*/
@Override
public MovementStatus update() {
ctx.player().capabilities.isFlying = false;
ctx.player().abilities.isFlying = false;
currentState = updateState(currentState);
if (MovementHelper.isLiquid(ctx, ctx.playerFeet())) {
currentState.setInput(Input.JUMP, true);
}
if (ctx.player().isEntityInsideOpaqueBlock()) {
ctx.getSelectedBlock().ifPresent(pos -> MovementHelper.switchToBestToolFor(ctx, BlockStateInterface.get(ctx, pos)));
currentState.setInput(Input.CLICK_LEFT, true);
}
@@ -140,14 +157,17 @@ public abstract class Movement implements IMovement, MovementHelper {
}
boolean somethingInTheWay = false;
for (BetterBlockPos blockPos : positionsToBreak) {
if (!MovementHelper.canWalkThrough(ctx, blockPos) && !(BlockStateInterface.getBlock(ctx, blockPos) instanceof BlockLiquid)) { // can't break liquid, so don't try
if (!ctx.world().getEntitiesWithinAABB(EntityFallingBlock.class, new AxisAlignedBB(0, 0, 0, 1, 1.1, 1).offset(blockPos)).isEmpty() && Baritone.settings().pauseMiningForFallingBlocks.value) {
return false;
}
if (!MovementHelper.canWalkThrough(ctx, blockPos)) { // can't break air, so don't try
somethingInTheWay = true;
MovementHelper.switchToBestToolFor(ctx, BlockStateInterface.get(ctx, blockPos));
Optional<Rotation> reachable = RotationUtils.reachable(ctx.player(), blockPos, ctx.playerController().getBlockReachDistance());
if (reachable.isPresent()) {
Rotation rotTowardsBlock = reachable.get();
MovementHelper.switchToBestToolFor(ctx, BlockStateInterface.get(ctx, blockPos));
state.setTarget(new MovementState.MovementTarget(rotTowardsBlock, true));
if (Objects.equals(ctx.getSelectedBlock().orElse(null), blockPos) || ctx.playerRotations().isReallyCloseTo(rotTowardsBlock)) {
if (ctx.isLookingAt(blockPos) || ctx.playerRotations().isReallyCloseTo(rotTowardsBlock)) {
state.setInput(Input.CLICK_LEFT, true);
}
return false;
@@ -156,7 +176,7 @@ public abstract class Movement implements IMovement, MovementHelper {
//i'm doing it anyway
//i dont care if theres snow in the way!!!!!!!
//you dont own me!!!!
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.player().getPositionEyes(1.0F),
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.player().getEyePosition(1.0F),
VecUtils.getBlockPosCenter(blockPos), ctx.playerRotations()), true)
);
// don't check selectedblock on this one, this is a fallback when we can't see any face directly, it's intended to be breaking the "incorrect" block
@@ -270,4 +290,8 @@ public abstract class Movement implements IMovement, MovementHelper {
}
return toWalkIntoCached;
}
public BlockPos[] toBreakAll() {
return positionsToBreak;
}
}

View File

@@ -25,12 +25,18 @@ import baritone.api.utils.*;
import baritone.api.utils.input.Input;
import baritone.pathing.movement.MovementState.MovementTarget;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import baritone.utils.ToolSet;
import net.minecraft.block.*;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.IBlockState;
import net.minecraft.fluid.FlowingFluid;
import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.IFluidState;
import net.minecraft.fluid.WaterFluid;
import net.minecraft.init.Blocks;
import net.minecraft.init.Fluids;
import net.minecraft.pathfinding.PathType;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.properties.SlabType;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
@@ -38,7 +44,7 @@ import net.minecraft.util.math.Vec3d;
import java.util.Optional;
import static baritone.pathing.movement.Movement.HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP;
import static baritone.pathing.movement.Movement.HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP;
/**
* Static helpers for cost calculation
@@ -52,11 +58,27 @@ public interface MovementHelper extends ActionCosts, Helper {
return b == Blocks.ICE // ice becomes water, and water can mess up the path
|| b instanceof BlockSilverfish // obvious reasons
// call context.get directly with x,y,z. no need to make 5 new BlockPos for no reason
|| bsi.get0(x, y + 1, z).getBlock() instanceof BlockLiquid//don't break anything touching liquid on any side
|| 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;
|| avoidAdjacentBreaking(bsi, x, y + 1, z, true)
|| avoidAdjacentBreaking(bsi, x + 1, y, z, false)
|| avoidAdjacentBreaking(bsi, x - 1, y, z, false)
|| avoidAdjacentBreaking(bsi, x, y, z + 1, false)
|| avoidAdjacentBreaking(bsi, x, y, z - 1, false);
}
static boolean avoidAdjacentBreaking(BlockStateInterface bsi, int x, int y, int z, boolean directlyAbove) {
// returns true if you should avoid breaking a block that's adjacent to this one (e.g. lava that will start flowing if you give it a path)
// this is only called for north, south, east, west, and up. this is NOT called for down.
// we assume that it's ALWAYS okay to break the block thats ABOVE liquid
IBlockState state = bsi.get0(x, y, z);
Block block = state.getBlock();
if (!directlyAbove // it is fine to mine a block that has a falling block directly above, this (the cost of breaking the stacked fallings) is included in cost calculations
// therefore if directlyAbove is true, we will actually ignore if this is falling
&& block instanceof BlockFalling // obviously, this check is only valid for falling blocks
&& Baritone.settings().avoidUpdatingFallingBlocks.value // and if the setting is enabled
&& BlockFalling.canFallThrough(bsi.get0(x, y - 1, z))) { // and if it would fall (i.e. it's unsupported)
return true; // dont break a block that is adjacent to unsupported gravel because it can cause really weird stuff
}
return !state.getFluidState().isEmpty();
}
static boolean canWalkThrough(IPlayerContext ctx, BetterBlockPos pos) {
@@ -69,10 +91,13 @@ public interface MovementHelper extends ActionCosts, Helper {
static boolean canWalkThrough(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
Block block = state.getBlock();
if (block == Blocks.AIR) { // early return for most common case
if (block instanceof BlockAir) { // early return for most common case
return true;
}
if (block == Blocks.FIRE || block == Blocks.TRIPWIRE || block == Blocks.WEB || block == Blocks.END_PORTAL || block == Blocks.COCOA || block instanceof BlockSkull || block instanceof BlockTrapDoor) {
if (block == Blocks.FIRE || block == Blocks.TRIPWIRE || block == Blocks.COBWEB || block == Blocks.END_PORTAL || block == Blocks.COCOA || block instanceof BlockAbstractSkull || block == Blocks.BUBBLE_COLUMN || block instanceof BlockShulkerBox || block instanceof BlockSlab || block instanceof BlockTrapDoor) {
return false;
}
if (Baritone.settings().blocksToAvoid.value.contains(block)) {
return false;
}
if (block instanceof BlockDoor || block instanceof BlockFenceGate) {
@@ -81,10 +106,10 @@ public interface MovementHelper extends ActionCosts, Helper {
// be opened by just interacting.
return block != Blocks.IRON_DOOR;
}
if (block == Blocks.CARPET) {
if (block instanceof BlockCarpet) {
return canWalkOn(bsi, x, y - 1, z);
}
if (block instanceof BlockSnow) {
if (block instanceof BlockSnowLayer) {
// we've already checked doors and fence gates
// so the only remaining dynamic isPassables are snow and trapdoor
// if they're cached as a top block, we don't know their metadata
@@ -94,7 +119,7 @@ public interface MovementHelper extends ActionCosts, Helper {
}
// 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
if (state.getValue(BlockSnow.LAYERS) >= 3) {
if (state.get(BlockSnowLayer.LAYERS) >= 3) {
return false;
}
// ok, it's low enough we could walk through it, but is it supported?
@@ -103,20 +128,21 @@ public interface MovementHelper extends ActionCosts, Helper {
if (isFlowing(x, y, z, state, bsi)) {
return false; // Don't walk through flowing liquids
}
if (block instanceof BlockLiquid) {
IFluidState fluidState = state.getFluidState();
if (fluidState.getFluid() instanceof WaterFluid) {
if (Baritone.settings().assumeWalkOnWater.value) {
return false;
}
IBlockState up = bsi.get0(x, y + 1, z);
if (up.getBlock() instanceof BlockLiquid || up.getBlock() instanceof BlockLilyPad) {
if (!up.getFluidState().isEmpty() || up.getBlock() instanceof BlockLilyPad) {
return false;
}
return block == Blocks.WATER || block == Blocks.FLOWING_WATER;
return true;
}
// every block that overrides isPassable with anything more complicated than a "return true;" or "return false;"
// has already been accounted for above
// therefore it's safe to not construct a blockpos from our x, y, z ints and instead just pass null
return block.isPassable(null, null);
return state.allowsMovement(null, null, PathType.LAND);
}
/**
@@ -135,27 +161,28 @@ public interface MovementHelper extends ActionCosts, Helper {
static boolean fullyPassable(IBlockState state) {
Block block = state.getBlock();
if (block == Blocks.AIR) { // early return for most common case
if (block instanceof BlockAir) { // early return for most common case
return true;
}
// exceptions - blocks that are isPassable true, but we can't actually jump through
if (block == Blocks.FIRE
|| block == Blocks.TRIPWIRE
|| block == Blocks.WEB
|| block == Blocks.COBWEB
|| block == Blocks.VINE
|| block == Blocks.LADDER
|| block == Blocks.COCOA
|| block instanceof BlockDoor
|| block instanceof BlockFenceGate
|| block instanceof BlockSnow
|| block instanceof BlockLiquid
|| !state.getFluidState().isEmpty()
|| block instanceof BlockTrapDoor
|| block instanceof BlockEndPortal
|| block instanceof BlockSkull) {
|| block instanceof BlockSkull
|| block instanceof BlockShulkerBox) {
return false;
}
// door, fence gate, liquid, trapdoor have been accounted for, nothing else uses the world or pos parameters
return block.isPassable(null, null);
return state.allowsMovement(null, null, PathType.LAND);
}
static boolean isReplacable(int x, int y, int z, IBlockState state, BlockStateInterface bsi) {
@@ -170,20 +197,19 @@ public interface MovementHelper extends ActionCosts, Helper {
* }
*/
Block block = state.getBlock();
if (block == Blocks.AIR || isWater(block)) {
if (block instanceof BlockAir) {
// early return for common cases hehe
return true;
}
if (block instanceof BlockSnow) {
if (block instanceof BlockSnowLayer) {
// as before, default to true (mostly because it would otherwise make long distance pathing through snowy biomes impossible)
if (!bsi.worldContainsLoadedChunk(x, z)) {
return true;
}
return state.getValue(BlockSnow.LAYERS) == 1;
return state.get(BlockSnowLayer.LAYERS) == 1;
}
if (block instanceof BlockDoublePlant) {
BlockDoublePlant.EnumPlantType kek = state.getValue(BlockDoublePlant.VARIANT);
return kek == BlockDoublePlant.EnumPlantType.FERN || kek == BlockDoublePlant.EnumPlantType.GRASS;
if (block == Blocks.LARGE_FERN || block == Blocks.TALL_GRASS) {
return true;
}
return state.getMaterial().isReplaceable();
}
@@ -211,16 +237,16 @@ public interface MovementHelper extends ActionCosts, Helper {
return true;
}
return state.getValue(BlockFenceGate.OPEN);
return state.get(BlockFenceGate.OPEN);
}
static boolean isHorizontalBlockPassable(BlockPos blockPos, IBlockState blockState, BlockPos playerPos, PropertyBool propertyOpen) {
static boolean isHorizontalBlockPassable(BlockPos blockPos, IBlockState blockState, BlockPos playerPos, BooleanProperty propertyOpen) {
if (playerPos.equals(blockPos)) {
return false;
}
EnumFacing.Axis facing = blockState.getValue(BlockHorizontal.FACING).getAxis();
boolean open = blockState.getValue(propertyOpen);
EnumFacing.Axis facing = blockState.get(BlockHorizontal.HORIZONTAL_FACING).getAxis();
boolean open = blockState.get(propertyOpen);
EnumFacing.Axis playerFacing;
if (playerPos.north().equals(blockPos) || playerPos.south().equals(blockPos)) {
@@ -234,14 +260,15 @@ public interface MovementHelper extends ActionCosts, Helper {
return (facing == playerFacing) == open;
}
static boolean avoidWalkingInto(Block block) {
return block instanceof BlockLiquid
|| block instanceof BlockDynamicLiquid
|| block == Blocks.MAGMA
static boolean avoidWalkingInto(IBlockState state) {
Block block = state.getBlock();
return !state.getFluidState().isEmpty()
|| block == Blocks.MAGMA_BLOCK
|| block == Blocks.CACTUS
|| block == Blocks.FIRE
|| block == Blocks.END_PORTAL
|| block == Blocks.WEB;
|| block == Blocks.COBWEB
|| block == Blocks.BUBBLE_COLUMN;
}
/**
@@ -258,7 +285,7 @@ public interface MovementHelper extends ActionCosts, Helper {
*/
static boolean canWalkOn(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
Block block = state.getBlock();
if (block == Blocks.AIR || block == Blocks.MAGMA) {
if (block instanceof BlockAir || block == Blocks.MAGMA_BLOCK || block == Blocks.BUBBLE_COLUMN) {
// early return for most common case (air)
// plus magma, which is a normal cube but it hurts you
return false;
@@ -275,30 +302,31 @@ public interface MovementHelper extends ActionCosts, Helper {
if (block == Blocks.ENDER_CHEST || block == Blocks.CHEST) {
return true;
}
if (isWater(block)) {
if (isWater(state)) {
// since this is called literally millions of times per second, the benefit of not allocating millions of useless "pos.up()"
// BlockPos s that we'd just garbage collect immediately is actually noticeable. I don't even think its a decrease in readability
Block up = bsi.get0(x, y + 1, z).getBlock();
if (up == Blocks.WATERLILY || up == Blocks.CARPET) {
IBlockState upState = bsi.get0(x, y + 1, z);
Block up = upState.getBlock();
if (up == Blocks.LILY_PAD || up instanceof BlockCarpet) {
return true;
}
if (isFlowing(x, y, z, state, bsi) || block == Blocks.FLOWING_WATER) {
if (isFlowing(x, y, z, state, bsi) || upState.getFluidState().getFluid() == Fluids.FLOWING_WATER) {
// the only scenario in which we can walk on flowing water is if it's under still water with jesus off
return isWater(up) && !Baritone.settings().assumeWalkOnWater.value;
return isWater(upState) && !Baritone.settings().assumeWalkOnWater.value;
}
// if assumeWalkOnWater is on, we can only walk on water if there isn't 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(upState) ^ Baritone.settings().assumeWalkOnWater.value;
}
if (block == Blocks.GLASS || block == Blocks.STAINED_GLASS) {
if (Baritone.settings().assumeWalkOnLava.value && isLava(state) && !isFlowing(x, y, z, state, bsi)) {
return true;
}
if (block == Blocks.GLASS || block instanceof BlockStainedGlass) {
return true;
}
if (block instanceof BlockSlab) {
if (!Baritone.settings().allowWalkOnBottomSlab.value) {
if (((BlockSlab) block).isDouble()) {
return true;
}
return state.getValue(BlockSlab.HALF) != BlockSlab.EnumBlockHalf.BOTTOM;
return state.isTopSolid();
}
return true;
}
@@ -309,6 +337,10 @@ public interface MovementHelper extends ActionCosts, Helper {
return canWalkOn(new BlockStateInterface(ctx), pos.x, pos.y, pos.z, state);
}
static boolean canWalkOn(IPlayerContext ctx, BlockPos pos) {
return canWalkOn(new BlockStateInterface(ctx), pos.getX(), pos.getY(), pos.getZ());
}
static boolean canWalkOn(IPlayerContext ctx, BetterBlockPos pos) {
return canWalkOn(new BlockStateInterface(ctx), pos.x, pos.y, pos.z);
}
@@ -333,7 +365,7 @@ public interface MovementHelper extends ActionCosts, Helper {
// can we look at the center of a side face of this block and likely be able to place?
// (thats how this check is used)
// therefore dont include weird things that we technically could place against (like carpet) but practically can't
return state.isBlockNormalCube() || state.isFullBlock() || state.getBlock() == Blocks.GLASS || state.getBlock() == Blocks.STAINED_GLASS;
return state.isBlockNormalCube() || state.isFullCube() || state.getBlock() == Blocks.GLASS || state.getBlock() instanceof BlockStainedGlass;
}
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, boolean includeFalling) {
@@ -343,6 +375,9 @@ public interface MovementHelper extends ActionCosts, Helper {
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, IBlockState state, boolean includeFalling) {
Block block = state.getBlock();
if (!canWalkThrough(context.bsi, x, y, z, state)) {
if (!state.getFluidState().isEmpty()) {
return COST_INF;
}
double mult = context.breakCostMultiplierAt(x, y, z);
if (mult >= COST_INF) {
return COST_INF;
@@ -350,16 +385,11 @@ public interface MovementHelper extends ActionCosts, Helper {
if (avoidBreaking(context.bsi, x, y, z, state)) {
return COST_INF;
}
if (block instanceof BlockLiquid) {
return COST_INF;
}
double m = Blocks.CRAFTING_TABLE.equals(block) ? 10 : 1; // TODO see if this is still necessary. it's from MineBot when we wanted to penalize breaking its crafting table
double strVsBlock = context.toolSet.getStrVsBlock(state);
if (strVsBlock <= 0) {
return COST_INF;
}
double result = m / strVsBlock;
double result = 1 / strVsBlock;
result += context.breakBlockAdditionalCost;
result *= mult;
if (includeFalling) {
@@ -375,8 +405,7 @@ public interface MovementHelper extends ActionCosts, Helper {
static boolean isBottomSlab(IBlockState state) {
return state.getBlock() instanceof BlockSlab
&& !((BlockSlab) state.getBlock()).isDouble()
&& state.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM;
&& state.get(BlockSlab.TYPE) == SlabType.BOTTOM;
}
/**
@@ -413,11 +442,12 @@ public interface MovementHelper extends ActionCosts, Helper {
* Returns whether or not the specified block is
* water, regardless of whether or not it is flowing.
*
* @param b The block
* @param state The block state
* @return Whether or not the block is water
*/
static boolean isWater(Block b) {
return b == Blocks.FLOWING_WATER || b == Blocks.WATER;
static boolean isWater(IBlockState state) {
Fluid f = state.getFluidState().getFluid();
return f == Fluids.WATER || f == Fluids.FLOWING_WATER;
}
/**
@@ -429,11 +459,12 @@ public interface MovementHelper extends ActionCosts, Helper {
* @return Whether or not the block is water
*/
static boolean isWater(IPlayerContext ctx, BlockPos bp) {
return isWater(BlockStateInterface.getBlock(ctx, bp));
return isWater(BlockStateInterface.get(ctx, bp));
}
static boolean isLava(Block b) {
return b == Blocks.FLOWING_LAVA || b == Blocks.LAVA;
static boolean isLava(IBlockState state) {
Fluid f = state.getFluidState().getFluid();
return f == Fluids.LAVA || f == Fluids.FLOWING_LAVA;
}
/**
@@ -444,20 +475,25 @@ public interface MovementHelper extends ActionCosts, Helper {
* @return Whether or not the block is a liquid
*/
static boolean isLiquid(IPlayerContext ctx, BlockPos p) {
return BlockStateInterface.getBlock(ctx, p) instanceof BlockLiquid;
return isLiquid(BlockStateInterface.get(ctx, p));
}
static boolean isLiquid(IBlockState blockState) {
return !blockState.getFluidState().isEmpty();
}
static boolean possiblyFlowing(IBlockState state) {
// Will be IFluidState in 1.13
return state.getBlock() instanceof BlockLiquid
&& state.getValue(BlockLiquid.LEVEL) != 0;
IFluidState fluidState = state.getFluidState();
return fluidState.getFluid() instanceof FlowingFluid
&& fluidState.getFluid().getLevel(fluidState) != 8;
}
static boolean isFlowing(int x, int y, int z, IBlockState state, BlockStateInterface bsi) {
if (!(state.getBlock() instanceof BlockLiquid)) {
IFluidState fluidState = state.getFluidState();
if (!(fluidState.getFluid() instanceof FlowingFluid)) {
return false;
}
if (state.getValue(BlockLiquid.LEVEL) != 0) {
if (fluidState.getFluid().getLevel(fluidState) != 8) {
return true;
}
return possiblyFlowing(bsi.get0(x + 1, y, z))
@@ -476,10 +512,10 @@ public interface MovementHelper extends ActionCosts, Helper {
found = true;
}
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 (!((Baritone) baritone).getInventoryBehavior().selectThrowawayForLocation(placeAt.getX(), placeAt.getY(), placeAt.getZ())) { // get ready to place a throwaway block
Helper.HELPER.logDebug("bb pls get me some blocks. dirt or cobble");
if (!((Baritone) baritone).getInventoryBehavior().selectThrowawayForLocation(false, placeAt.getX(), placeAt.getY(), placeAt.getZ())) { // get ready to place a throwaway block
Helper.HELPER.logDebug("bb pls get me some blocks. dirt, netherrack, cobble");
state.setStatus(MovementStatus.UNREACHABLE);
return PlaceResult.NO_OPTION;
}
@@ -488,7 +524,7 @@ public interface MovementHelper extends ActionCosts, Helper {
double faceZ = (placeAt.getZ() + against1.getZ() + 1.0D) * 0.5D;
Rotation place = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations());
RayTraceResult res = RayTraceUtils.rayTraceTowards(ctx.player(), place, ctx.playerController().getBlockReachDistance());
if (res != null && res.typeOfHit == RayTraceResult.Type.BLOCK && res.getBlockPos().equals(against1) && res.getBlockPos().offset(res.sideHit).equals(placeAt)) {
if (res != null && res.type == RayTraceResult.Type.BLOCK && res.getBlockPos().equals(against1) && res.getBlockPos().offset(res.sideHit).equals(placeAt)) {
state.setTarget(new MovementState.MovementTarget(place, true));
found = true;
@@ -505,10 +541,15 @@ public interface MovementHelper extends ActionCosts, Helper {
EnumFacing side = ctx.objectMouseOver().sideHit;
// only way for selectedBlock.equals(placeAt) to be true is if it's replacable
if (selectedBlock.equals(placeAt) || (MovementHelper.canPlaceAgainst(ctx, selectedBlock) && selectedBlock.offset(side).equals(placeAt))) {
((Baritone) baritone).getInventoryBehavior().selectThrowawayForLocation(true, placeAt.getX(), placeAt.getY(), placeAt.getZ());
return PlaceResult.READY_TO_PLACE;
}
}
return found ? PlaceResult.ATTEMPTING : PlaceResult.NO_OPTION;
if (found) {
((Baritone) baritone).getInventoryBehavior().selectThrowawayForLocation(true, placeAt.getX(), placeAt.getY(), placeAt.getZ());
return PlaceResult.ATTEMPTING;
}
return PlaceResult.NO_OPTION;
}
enum PlaceResult {

View File

@@ -27,11 +27,14 @@ import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.utils.BlockStateInterface;
import com.google.common.collect.ImmutableSet;
import net.minecraft.block.BlockFalling;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumFacing;
import java.util.Set;
public class MovementAscend extends Movement {
private int ticksWithoutPlacement = 0;
@@ -51,6 +54,17 @@ public class MovementAscend extends Movement {
return cost(context, src.x, src.y, src.z, dest.x, dest.z);
}
@Override
protected Set<BetterBlockPos> calculateValidPositions() {
BetterBlockPos prior = new BetterBlockPos(src.subtract(getDirection()).up()); // sometimes we back up to place the block, also sprint ascends, also skip descend to straight ascend
return ImmutableSet.of(src,
src.up(),
dest,
prior,
prior.up()
);
}
public static double cost(CalculationContext context, int x, int y, int z, int destX, int destZ) {
IBlockState toPlace = context.get(destX, y, destZ);
double additionalPlacementCost = 0;
@@ -64,9 +78,9 @@ public class MovementAscend extends Movement {
}
boolean foundPlaceOption = false;
for (int i = 0; i < 5; i++) {
int againstX = destX + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getXOffset();
int againstY = y + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getYOffset();
int againstZ = destZ + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getZOffset();
int againstX = destX + HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP[i].getXOffset();
int againstY = y + HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP[i].getYOffset();
int againstZ = destZ + HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP[i].getZOffset();
if (againstX == x && againstZ == z) { // we might be able to backplace now, but it doesn't matter because it will have been broken by the time we'd need to use it
continue;
}
@@ -143,6 +157,10 @@ public class MovementAscend extends Movement {
@Override
public MovementState updateState(MovementState state) {
if (ctx.playerFeet().y < src.y) {
// this check should run even when in preparing state (breaking blocks)
return state.setStatus(MovementStatus.UNREACHABLE);
}
super.updateState(state);
// TODO incorporate some behavior from ActionClimb (specifically how it waited until it was at most 1.2 blocks away before starting to jump
// for efficiency in ascending minimal height staircases, which is just repeated MovementAscend, so that it doesn't bonk its head on the ceiling repeatedly)
@@ -154,10 +172,6 @@ public class MovementAscend extends Movement {
return state.setStatus(MovementStatus.SUCCESS);
}
if (ctx.playerFeet().y < src.y) {
return state.setStatus(MovementStatus.UNREACHABLE);
}
IBlockState jumpingOnto = BlockStateInterface.get(ctx, positionToPlace);
if (!MovementHelper.canWalkOn(ctx, positionToPlace, jumpingOnto)) {
ticksWithoutPlacement++;
@@ -198,8 +212,6 @@ public class MovementAscend extends Movement {
return state.setInput(Input.JUMP, true);
}
// System.out.println(flatDistToNext + " " + sideDist);
if (flatDistToNext > 1.2 || sideDist > 0.2) {
return state;
}

View File

@@ -29,6 +29,7 @@ import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.utils.BlockStateInterface;
import baritone.utils.pathing.MutableMoveResult;
import com.google.common.collect.ImmutableSet;
import net.minecraft.block.Block;
import net.minecraft.block.BlockFalling;
import net.minecraft.block.state.IBlockState;
@@ -37,6 +38,8 @@ import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import java.util.Set;
public class MovementDescend extends Movement {
private int numTicks = 0;
@@ -61,6 +64,11 @@ public class MovementDescend extends Movement {
return result.cost;
}
@Override
protected Set<BetterBlockPos> calculateValidPositions() {
return ImmutableSet.of(src, dest.up(), dest);
}
public static void cost(CalculationContext context, int x, int y, int z, int destX, int destZ, MutableMoveResult res) {
double totalCost = 0;
IBlockState destDown = context.get(destX, y - 1, destZ);
@@ -137,7 +145,7 @@ public class MovementDescend extends Movement {
IBlockState ontoBlock = context.get(destX, newY, destZ);
int unprotectedFallHeight = fallHeight - (y - effectiveStartHeight); // equal to fallHeight - y + effectiveFallHeight, which is equal to -newY + effectiveFallHeight, which is equal to effectiveFallHeight - newY
double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[unprotectedFallHeight] + frontBreak + costSoFar;
if (MovementHelper.isWater(ontoBlock.getBlock())) {
if (MovementHelper.isWater(ontoBlock)) {
if (!MovementHelper.canWalkThrough(context.bsi, destX, newY, destZ, ontoBlock)) {
return false;
}
@@ -216,7 +224,7 @@ public class MovementDescend extends Movement {
double destZ = (src.getZ() + 0.5) * 0.17 + (dest.getZ() + 0.5) * 0.83;
EntityPlayerSP player = ctx.player();
state.setTarget(new MovementState.MovementTarget(
new Rotation(RotationUtils.calcRotationFromVec3d(player.getPositionEyes(1.0F),
new Rotation(RotationUtils.calcRotationFromVec3d(player.getEyePosition(1.0F),
new Vec3d(destX, dest.getY(), destZ),
new Rotation(player.rotationYaw, player.rotationPitch)).getYaw(), player.rotationPitch),
false
@@ -248,7 +256,7 @@ public class MovementDescend extends Movement {
return true;
}
for (int y = 0; y <= 2; y++) { // we could hit any of the three blocks
if (MovementHelper.avoidWalkingInto(BlockStateInterface.getBlock(ctx, into.up(y)))) {
if (MovementHelper.avoidWalkingInto(BlockStateInterface.get(ctx, into.up(y)))) {
return true;
}
}

View File

@@ -28,6 +28,7 @@ import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.utils.BlockStateInterface;
import baritone.utils.pathing.MutableMoveResult;
import com.google.common.collect.ImmutableSet;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
@@ -36,6 +37,7 @@ import net.minecraft.util.math.BlockPos;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class MovementDiagonal extends Movement {
@@ -64,6 +66,16 @@ public class MovementDiagonal extends Movement {
return result.cost;
}
@Override
protected Set<BetterBlockPos> calculateValidPositions() {
BetterBlockPos diagA = new BetterBlockPos(src.x, src.y, dest.z);
BetterBlockPos diagB = new BetterBlockPos(dest.x, src.y, src.z);
if (dest.y != src.y) { // only if allowDiagonalDescend
return ImmutableSet.of(src, dest.up(), diagA, diagB, dest, diagA.down(), diagB.down());
}
return ImmutableSet.of(src, dest, diagA, diagB);
}
public static void cost(CalculationContext context, int x, int y, int z, int destX, int destZ, MutableMoveResult res) {
IBlockState destInto = context.get(destX, y, destZ);
if (!MovementHelper.canWalkThrough(context.bsi, destX, y, destZ, destInto) || !MovementHelper.canWalkThrough(context.bsi, destX, y + 1, destZ)) {
@@ -91,12 +103,12 @@ public class MovementDiagonal extends Movement {
if (fromDown == Blocks.SOUL_SAND) {
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
}
Block cuttingOver1 = context.get(x, y - 1, destZ).getBlock();
if (cuttingOver1 == Blocks.MAGMA || MovementHelper.isLava(cuttingOver1)) {
IBlockState cuttingOver1 = context.get(x, y - 1, destZ);
if (cuttingOver1.getBlock() == Blocks.MAGMA_BLOCK || MovementHelper.isLava(cuttingOver1)) {
return;
}
Block cuttingOver2 = context.get(destX, y - 1, z).getBlock();
if (cuttingOver2 == Blocks.MAGMA || MovementHelper.isLava(cuttingOver2)) {
IBlockState cuttingOver2 = context.get(destX, y - 1, z);
if (cuttingOver2.getBlock() == Blocks.MAGMA_BLOCK || MovementHelper.isLava(cuttingOver2)) {
return;
}
IBlockState pb0 = context.get(x, y, destZ);
@@ -115,7 +127,7 @@ public class MovementDiagonal extends Movement {
return;
}
IBlockState pb3 = context.get(destX, y + 1, z);
if (optionA == 0 && ((MovementHelper.avoidWalkingInto(pb2.getBlock()) && pb2.getBlock() != Blocks.WATER) || MovementHelper.avoidWalkingInto(pb3.getBlock()))) {
if (optionA == 0 && ((MovementHelper.avoidWalkingInto(pb2) && pb2.getBlock() != Blocks.WATER) || MovementHelper.avoidWalkingInto(pb3))) {
// at this point we're done calculating optionA, so we can check if it's actually possible to edge around in that direction
return;
}
@@ -124,13 +136,14 @@ public class MovementDiagonal extends Movement {
// and finally, if the cost is nonzero for both ways to approach this diagonal, it's not possible
return;
}
if (optionB == 0 && ((MovementHelper.avoidWalkingInto(pb0.getBlock()) && pb0.getBlock() != Blocks.WATER) || MovementHelper.avoidWalkingInto(pb1.getBlock()))) {
if (optionB == 0 && ((MovementHelper.avoidWalkingInto(pb0) && pb0.getBlock() != Blocks.WATER) || MovementHelper.avoidWalkingInto(pb1))) {
// and now that option B is fully calculated, see if we can edge around that way
return;
}
boolean water = false;
Block startIn = context.getBlock(x, y, z);
if (MovementHelper.isWater(startIn) || MovementHelper.isWater(destInto.getBlock())) {
IBlockState startState = context.get(x, y, z);
Block startIn = startState.getBlock();
if (MovementHelper.isWater(startState) || MovementHelper.isWater(destInto)) {
// Ignore previous multiplier
// Whatever we were walking on (possibly soul sand) doesn't matter as we're actually floating on water
// Not even touching the blocks below
@@ -171,8 +184,9 @@ public class MovementDiagonal extends Movement {
}
if (ctx.playerFeet().equals(dest)) {
state.setStatus(MovementStatus.SUCCESS);
return state;
return state.setStatus(MovementStatus.SUCCESS);
} else if (!playerInValidPosition() && !(MovementHelper.isLiquid(ctx, src) && getValidPositions().contains(ctx.playerFeet().up()))) {
return state.setStatus(MovementStatus.UNREACHABLE);
}
if (sprint()) {
state.setInput(Input.SPRINT, true);
@@ -181,7 +195,7 @@ public class MovementDiagonal extends Movement {
return state;
}
public boolean sprint() {
private boolean sprint() {
if (MovementHelper.isLiquid(ctx, ctx.playerFeet()) && !Baritone.settings().sprintInWater.value) {
return false;
}

View File

@@ -24,10 +24,13 @@ import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import com.google.common.collect.ImmutableSet;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import java.util.Set;
public class MovementDownward extends Movement {
private int numTicks = 0;
@@ -47,7 +50,15 @@ public class MovementDownward extends Movement {
return cost(context, src.x, src.y, src.z);
}
@Override
protected Set<BetterBlockPos> calculateValidPositions() {
return ImmutableSet.of(src, dest);
}
public static double cost(CalculationContext context, int x, int y, int z) {
if (!context.allowDownward) {
return COST_INF;
}
if (!MovementHelper.canWalkOn(context.bsi, x, y - 2, z)) {
return COST_INF;
}
@@ -70,6 +81,8 @@ public class MovementDownward extends Movement {
if (ctx.playerFeet().equals(dest)) {
return state.setStatus(MovementStatus.SUCCESS);
} else if (!playerInValidPosition()) {
return state.setStatus(MovementStatus.UNREACHABLE);
}
double diffX = ctx.player().posX - (dest.getX() + 0.5);
double diffZ = ctx.player().posZ - (dest.getZ() + 0.5);

View File

@@ -34,16 +34,18 @@ import net.minecraft.block.Block;
import net.minecraft.block.BlockLadder;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.fluid.WaterFluid;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
public class MovementFall extends Movement {
@@ -64,6 +66,16 @@ public class MovementFall extends Movement {
return result.cost;
}
@Override
protected Set<BetterBlockPos> calculateValidPositions() {
Set<BetterBlockPos> set = new HashSet<>();
set.add(src);
for (int y = src.y - dest.y; y >= 0; y--) {
set.add(dest.up(y));
}
return set;
}
private boolean willPlaceBucket() {
CalculationContext context = new CalculationContext(baritone);
MutableMoveResult result = new MutableMoveResult();
@@ -80,10 +92,11 @@ public class MovementFall extends Movement {
BlockPos playerFeet = ctx.playerFeet();
Rotation toDest = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest), ctx.playerRotations());
Rotation targetRotation = null;
Block destBlock = ctx.world().getBlockState(dest).getBlock();
boolean isWater = destBlock == Blocks.WATER || destBlock == Blocks.FLOWING_WATER;
IBlockState destState = ctx.world().getBlockState(dest);
Block destBlock = destState.getBlock();
boolean isWater = destState.getFluidState().getFluid() instanceof WaterFluid;
if (!isWater && willPlaceBucket() && !playerFeet.equals(dest)) {
if (!InventoryPlayer.isHotbar(ctx.player().inventory.getSlotFor(STACK_BUCKET_WATER)) || ctx.world().provider.isNether()) {
if (!InventoryPlayer.isHotbar(ctx.player().inventory.getSlotFor(STACK_BUCKET_WATER)) || ctx.world().getDimension().isNether()) {
return state.setStatus(MovementStatus.UNREACHABLE);
}
@@ -92,8 +105,7 @@ public class MovementFall extends Movement {
targetRotation = new Rotation(toDest.getYaw(), 90.0F);
RayTraceResult trace = ctx.objectMouseOver();
if (trace != null && trace.typeOfHit == RayTraceResult.Type.BLOCK && (trace.getBlockPos().equals(dest) || trace.getBlockPos().equals(dest.down()))) {
if (ctx.isLookingAt(dest) || ctx.isLookingAt(dest.down())) {
state.setInput(Input.CLICK_RIGHT, true);
}
}
@@ -150,7 +162,7 @@ public class MovementFall extends Movement {
for (int i = 0; i < 15; i++) {
IBlockState state = ctx.world().getBlockState(ctx.playerFeet().down(i));
if (state.getBlock() == Blocks.LADDER) {
return state.getValue(BlockLadder.FACING);
return state.get(BlockLadder.FACING);
}
}
return null;

View File

@@ -28,12 +28,16 @@ import baritone.pathing.movement.MovementState;
import baritone.utils.BlockStateInterface;
import baritone.utils.pathing.MutableMoveResult;
import net.minecraft.block.Block;
import net.minecraft.block.BlockLiquid;
import net.minecraft.block.BlockStairs;
import net.minecraft.block.state.IBlockState;
import net.minecraft.fluid.WaterFluid;
import net.minecraft.init.Blocks;
import net.minecraft.init.Fluids;
import net.minecraft.util.EnumFacing;
import java.util.HashSet;
import java.util.Set;
public class MovementParkour extends Movement {
private static final BetterBlockPos[] EMPTY = new BetterBlockPos[]{};
@@ -73,7 +77,7 @@ public class MovementParkour extends Movement {
// second most common case -- we could just traverse not parkour
return;
}
if (MovementHelper.avoidWalkingInto(adj.getBlock()) && adj.getBlock() != Blocks.WATER && adj.getBlock() != Blocks.FLOWING_WATER) { // magma sucks
if (MovementHelper.avoidWalkingInto(adj) && !(adj.getFluidState().getFluid() instanceof WaterFluid)) { // magma sucks
return;
}
if (!MovementHelper.fullyPassable(context, x + xDiff, y + 1, z + zDiff)) {
@@ -86,7 +90,7 @@ public class MovementParkour extends Movement {
return;
}
IBlockState standingOn = context.get(x, y - 1, z);
if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || standingOn.getBlock() instanceof BlockStairs || MovementHelper.isBottomSlab(standingOn) || standingOn.getBlock() instanceof BlockLiquid) {
if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || standingOn.getBlock() instanceof BlockStairs || MovementHelper.isBottomSlab(standingOn) || standingOn.getFluidState().getFluid() != Fluids.EMPTY) {
return;
}
int maxJump;
@@ -106,7 +110,9 @@ public class MovementParkour extends Movement {
return;
}
}
if (MovementHelper.canWalkOn(context.bsi, x + xDiff * i, y - 1, z + zDiff * i)) {
IBlockState landingOn = context.bsi.get0(x + xDiff * i, y - 1, z + zDiff * i);
// farmland needs to be canwalkon otherwise farm can never work at all, but we want to specifically disallow ending a jumy on farmland haha
if (landingOn.getBlock() != Blocks.FARMLAND && MovementHelper.canWalkOn(context.bsi, x + xDiff * i, y - 1, z + zDiff * i, landingOn)) {
res.x = x + xDiff * i;
res.y = y;
res.z = z + zDiff * i;
@@ -132,9 +138,9 @@ public class MovementParkour extends Movement {
return;
}
for (int i = 0; i < 5; i++) {
int againstX = destX + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getXOffset();
int againstY = y - 1 + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getYOffset();
int againstZ = destZ + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getZOffset();
int againstX = destX + HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP[i].getXOffset();
int againstY = y - 1 + HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP[i].getYOffset();
int againstZ = destZ + HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP[i].getZOffset();
if (againstX == x + xDiff * 3 && againstZ == z + zDiff * 3) { // we can't turn around that fast
continue;
}
@@ -172,6 +178,17 @@ public class MovementParkour extends Movement {
return res.cost;
}
@Override
protected Set<BetterBlockPos> calculateValidPositions() {
Set<BetterBlockPos> set = new HashSet<>();
for (int i = 0; i <= dist; i++) {
for (int y = 0; y < 2; y++) {
set.add(src.offset(direction, i).up(y));
}
}
return set;
}
@Override
public boolean safeToCancel(MovementState state) {
// once this movement is instantiated, the state is default to PREPPING
@@ -210,7 +227,7 @@ public class MovementParkour extends Movement {
state.setStatus(MovementStatus.SUCCESS);
}
} else if (!ctx.playerFeet().equals(src)) {
if (ctx.playerFeet().equals(src.offset(direction)) || ctx.player().posY - ctx.playerFeet().getY() > 0.0001) {
if (ctx.playerFeet().equals(src.offset(direction)) || ctx.player().posY - src.y > 0.0001) {
if (!MovementHelper.canWalkOn(ctx, dest.down()) && !ctx.player().onGround && MovementHelper.attemptToPlaceABlock(state, baritone, dest.down(), true) == PlaceResult.READY_TO_PLACE) {
// go in the opposite order to check DOWN before all horizontals -- down is preferable because you don't have to look to the side while in midair, which could mess up the trajectory
state.setInput(Input.CLICK_RIGHT, true);

View File

@@ -30,6 +30,7 @@ import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.utils.BlockStateInterface;
import com.google.common.collect.ImmutableSet;
import net.minecraft.block.*;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
@@ -37,7 +38,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
public class MovementPillar extends Movement {
@@ -50,15 +51,21 @@ public class MovementPillar extends Movement {
return cost(context, src.x, src.y, src.z);
}
@Override
protected Set<BetterBlockPos> calculateValidPositions() {
return ImmutableSet.of(src, dest);
}
public static double cost(CalculationContext context, int x, int y, int z) {
Block from = context.get(x, y, z).getBlock();
IBlockState fromState = context.get(x, y, z);
Block from = fromState.getBlock();
boolean ladder = from == Blocks.LADDER || from == Blocks.VINE;
IBlockState fromDown = context.get(x, y - 1, z);
if (!ladder) {
if (fromDown.getBlock() == Blocks.LADDER || fromDown.getBlock() == Blocks.VINE) {
return COST_INF; // can't pillar from a ladder or vine onto something that isn't also climbable
}
if (fromDown.getBlock() instanceof BlockSlab && !((BlockSlab) fromDown.getBlock()).isDouble() && fromDown.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM) {
if (fromDown.getBlock() instanceof BlockSlab && !fromDown.isTopSolid()) {
return COST_INF; // can't pillar up from a bottom slab onto a non ladder
}
}
@@ -70,9 +77,9 @@ public class MovementPillar extends Movement {
if (toBreakBlock instanceof BlockFenceGate) { // see issue #172
return COST_INF;
}
Block srcUp = null;
if (MovementHelper.isWater(toBreakBlock) && MovementHelper.isWater(from)) { // TODO should this also be allowed if toBreakBlock is air?
srcUp = context.get(x, y + 1, z).getBlock();
IBlockState srcUp = null;
if (MovementHelper.isWater(toBreak) && MovementHelper.isWater(fromState)) { // TODO should this also be allowed if toBreakBlock is air?
srcUp = context.get(x, y + 1, z);
if (MovementHelper.isWater(srcUp)) {
return LADDER_UP_ONE_COST; // allow ascending pillars of water, but only if we're already in one
}
@@ -84,11 +91,11 @@ public class MovementPillar extends Movement {
if (placeCost >= COST_INF) {
return COST_INF;
}
if (fromDown.getBlock() == Blocks.AIR) {
if (fromDown.getBlock() instanceof BlockAir) {
placeCost += 0.1; // slightly (1/200th of a second) penalize pillaring on what's currently air
}
}
if (from instanceof BlockLiquid || (fromDown.getBlock() instanceof BlockLiquid && context.assumeWalkOnWater)) {
if ((MovementHelper.isLiquid(fromState) && !MovementHelper.canPlaceAgainst(context.bsi, x, y - 1, z, fromDown)) || (MovementHelper.isLiquid(fromDown) && context.assumeWalkOnWater)) {
// otherwise, if we're standing in water, we cannot pillar
// if we're standing on water and assumeWalkOnWater is true, we cannot pillar
// if we're standing on water and assumeWalkOnWater is false, we must have ascended to here, or sneak backplaced, so it is possible to pillar again
@@ -106,9 +113,9 @@ public class MovementPillar extends Movement {
if (check.getBlock() instanceof BlockFalling) {
// see MovementAscend's identical check for breaking a falling block above our head
if (srcUp == null) {
srcUp = context.get(x, y + 1, z).getBlock();
srcUp = context.get(x, y + 1, z);
}
if (!(toBreakBlock instanceof BlockFalling) || !(srcUp instanceof BlockFalling)) {
if (!(toBreakBlock instanceof BlockFalling) || !(srcUp.getBlock() instanceof BlockFalling)) {
return COST_INF;
}
}
@@ -163,7 +170,7 @@ public class MovementPillar extends Movement {
}
IBlockState fromDown = BlockStateInterface.get(ctx, src);
if (MovementHelper.isWater(fromDown.getBlock()) && MovementHelper.isWater(ctx, dest)) {
if (MovementHelper.isWater(fromDown) && MovementHelper.isWater(ctx, dest)) {
// stay centered while swimming up a water column
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest), ctx.playerRotations()), false));
Vec3d destCenter = VecUtils.getBlockPosCenter(dest);
@@ -177,7 +184,7 @@ public class MovementPillar extends Movement {
}
boolean ladder = fromDown.getBlock() == Blocks.LADDER || fromDown.getBlock() == Blocks.VINE;
boolean vine = fromDown.getBlock() == Blocks.VINE;
Rotation rotation = RotationUtils.calcRotationFromVec3d(ctx.player().getPositionEyes(1.0F),
Rotation rotation = RotationUtils.calcRotationFromVec3d(ctx.player().getEyePosition(1.0F),
VecUtils.getBlockPosCenter(positionToPlace),
new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch));
if (!ladder) {
@@ -186,7 +193,7 @@ public class MovementPillar extends Movement {
boolean blockIsThere = MovementHelper.canWalkOn(ctx, src) || ladder;
if (ladder) {
BlockPos against = vine ? getAgainst(new CalculationContext(baritone), src) : src.offset(fromDown.getValue(BlockLadder.FACING).getOpposite());
BlockPos against = vine ? getAgainst(new CalculationContext(baritone), src) : src.offset(fromDown.get(BlockLadder.FACING).getOpposite());
if (against == null) {
logDebug("Unable to climb vines");
return state.setStatus(MovementStatus.UNREACHABLE);
@@ -208,7 +215,7 @@ public class MovementPillar extends Movement {
return state;
} else {
// Get ready to place a throwaway block
if (!((Baritone) baritone).getInventoryBehavior().selectThrowawayForLocation(src.x, src.y, src.z)) {
if (!((Baritone) baritone).getInventoryBehavior().selectThrowawayForLocation(true, src.x, src.y, src.z)) {
return state.setStatus(MovementStatus.UNREACHABLE);
}
@@ -240,10 +247,9 @@ public class MovementPillar extends Movement {
Block fr = frState.getBlock();
// TODO: Evaluate usage of getMaterial().isReplaceable()
if (!(fr instanceof BlockAir || frState.getMaterial().isReplaceable())) {
Optional<Rotation> reachable = RotationUtils.reachable(ctx.player(), src, ctx.playerController().getBlockReachDistance());
if (reachable.isPresent()) {
state.setTarget(new MovementState.MovementTarget(reachable.get(), true));
}
RotationUtils.reachable(ctx.player(), src, ctx.playerController().getBlockReachDistance())
.map(rot -> new MovementState.MovementTarget(rot, true))
.ifPresent(state::setTarget);
state.setInput(Input.JUMP, false); // breaking is like 5x slower when you're jumping
state.setInput(Input.CLICK_LEFT, true);
blockIsThere = false;

View File

@@ -30,16 +30,16 @@ import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.utils.BlockStateInterface;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.BlockFenceGate;
import net.minecraft.block.BlockSlab;
import com.google.common.collect.ImmutableSet;
import net.minecraft.block.*;
import net.minecraft.block.state.IBlockState;
import net.minecraft.fluid.WaterFluid;
import net.minecraft.init.Blocks;
import net.minecraft.state.properties.SlabType;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import java.util.Objects;
import java.util.Set;
public class MovementTraverse extends Movement {
@@ -63,15 +63,21 @@ public class MovementTraverse extends Movement {
return cost(context, src.x, src.y, src.z, dest.x, dest.z);
}
@Override
protected Set<BetterBlockPos> calculateValidPositions() {
return ImmutableSet.of(src, dest);
}
public static double cost(CalculationContext context, int x, int y, int z, int destX, int destZ) {
IBlockState pb0 = context.get(destX, y + 1, destZ);
IBlockState pb1 = context.get(destX, y, destZ);
IBlockState destOn = context.get(destX, y - 1, destZ);
Block srcDown = context.getBlock(x, y - 1, z);
IBlockState down = context.get(x, y - 1, z);
Block srcDown = down.getBlock();
if (MovementHelper.canWalkOn(context.bsi, destX, y - 1, destZ, destOn)) {//this is a walk, not a bridge
double WC = WALK_ONE_BLOCK_COST;
boolean water = false;
if (MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock())) {
if (MovementHelper.isWater(pb0) || MovementHelper.isWater(pb1)) {
WC = context.waterWalkSpeed;
water = true;
} else {
@@ -108,8 +114,8 @@ public class MovementTraverse extends Movement {
return COST_INF;
}
if (MovementHelper.isReplacable(destX, y - 1, destZ, destOn, context.bsi)) {
boolean throughWater = MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock());
if (MovementHelper.isWater(destOn.getBlock()) && throughWater) {
boolean throughWater = MovementHelper.isWater(pb0) || MovementHelper.isWater(pb1);
if (MovementHelper.isWater(destOn) && throughWater) {
// this happens when assume walk on water is true and this is a traverse in water, which isn't allowed
return COST_INF;
}
@@ -124,9 +130,9 @@ public class MovementTraverse extends Movement {
double hardness2 = MovementHelper.getMiningDurationTicks(context, destX, y + 1, destZ, pb0, true); // only include falling on the upper block to break
double WC = throughWater ? context.waterWalkSpeed : WALK_ONE_BLOCK_COST;
for (int i = 0; i < 5; i++) {
int againstX = destX + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getXOffset();
int againstY = y - 1 + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getYOffset();
int againstZ = destZ + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getZOffset();
int againstX = destX + HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP[i].getXOffset();
int againstY = y - 1 + HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP[i].getYOffset();
int againstZ = destZ + HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP[i].getZOffset();
if (againstX == x && againstZ == z) { // this would be a backplace
continue;
}
@@ -135,10 +141,10 @@ public class MovementTraverse extends Movement {
}
}
// now that we've checked all possible directions to side place, we actually need to backplace
if (srcDown == Blocks.SOUL_SAND || (srcDown instanceof BlockSlab && !((BlockSlab) srcDown).isDouble())) {
if (srcDown == Blocks.SOUL_SAND || (srcDown instanceof BlockSlab && down.get(BlockSlab.TYPE) != SlabType.DOUBLE)) {
return COST_INF; // can't sneak and backplace against soul sand or half slabs (regardless of whether it's top half or bottom half) =/
}
if (srcDown == Blocks.FLOWING_WATER || srcDown == Blocks.WATER) {
if (down.getFluidState() instanceof WaterFluid) {
return COST_INF; // this is obviously impossible
}
WC = WC * (SNEAK_ONE_BLOCK_COST / WALK_ONE_BLOCK_COST);//since we are sneak backplacing, we are sneaking lol
@@ -151,6 +157,8 @@ public class MovementTraverse extends Movement {
@Override
public MovementState updateState(MovementState state) {
super.updateState(state);
IBlockState pb0 = BlockStateInterface.get(ctx, positionsToBreak[0]);
IBlockState pb1 = BlockStateInterface.get(ctx, positionsToBreak[1]);
if (state.getStatus() != MovementStatus.RUNNING) {
// if the setting is enabled
if (!Baritone.settings().walkWhileBreaking.value) {
@@ -161,10 +169,10 @@ public class MovementTraverse extends Movement {
return state;
}
// and if it's fine to walk into the blocks in front
if (MovementHelper.avoidWalkingInto(BlockStateInterface.get(ctx, positionsToBreak[0]).getBlock())) {
if (MovementHelper.avoidWalkingInto(pb0)) {
return state;
}
if (MovementHelper.avoidWalkingInto(BlockStateInterface.get(ctx, positionsToBreak[1]).getBlock())) {
if (MovementHelper.avoidWalkingInto(pb1)) {
return state;
}
// and we aren't already pressed up against the block
@@ -172,14 +180,23 @@ public class MovementTraverse extends Movement {
if (dist < 0.83) {
return state;
}
if (!state.getTarget().getRotation().isPresent()) {
// this can happen rarely when the server lags and doesn't send the falling sand entity until you've already walked through the block and are now mining the next one
return state;
}
// combine the yaw to the center of the destination, and the pitch to the specific block we're trying to break
// it's safe to do this since the two blocks we break (in a traverse) are right on top of each other and so will have the same yaw
float yawToDest = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), dest), ctx.playerRotations()).getYaw();
float pitchToBreak = state.getTarget().getRotation().get().getPitch();
if ((pb0.isFullCube() || pb0.getBlock() instanceof BlockAir && (pb1.isFullCube() || pb1.getBlock() instanceof BlockAir))) {
// in the meantime, before we're right up against the block, we can break efficiently at this angle
pitchToBreak = 26;
}
state.setTarget(new MovementState.MovementTarget(new Rotation(yawToDest, pitchToBreak), true));
return state.setInput(Input.MOVE_FORWARD, true).setInput(Input.SPRINT, true);
return state.setTarget(new MovementState.MovementTarget(new Rotation(yawToDest, pitchToBreak), true))
.setInput(Input.MOVE_FORWARD, true)
.setInput(Input.SPRINT, true);
}
//sneak may have been set to true in the PREPPING state while mining an adjacent block
@@ -187,31 +204,19 @@ public class MovementTraverse extends Movement {
Block fd = BlockStateInterface.get(ctx, src.down()).getBlock();
boolean ladder = fd == Blocks.LADDER || fd == Blocks.VINE;
IBlockState pb0 = BlockStateInterface.get(ctx, positionsToBreak[0]);
IBlockState pb1 = BlockStateInterface.get(ctx, positionsToBreak[1]);
boolean door = pb0.getBlock() instanceof BlockDoor || pb1.getBlock() instanceof BlockDoor;
if (door) {
boolean isDoorActuallyBlockingUs = false;
if (pb0.getBlock() instanceof BlockDoor && !MovementHelper.isDoorPassable(ctx, src, dest)) {
isDoorActuallyBlockingUs = true;
} else if (pb1.getBlock() instanceof BlockDoor && !MovementHelper.isDoorPassable(ctx, dest, src)) {
isDoorActuallyBlockingUs = true;
}
if (isDoorActuallyBlockingUs && !(Blocks.IRON_DOOR.equals(pb0.getBlock()) || Blocks.IRON_DOOR.equals(pb1.getBlock()))) {
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), positionsToBreak[0]), ctx.playerRotations()), true))
.setInput(Input.CLICK_RIGHT, true);
}
if ((pb0.getBlock() instanceof BlockDoor || pb1.getBlock() instanceof BlockDoor)
&& (pb0.getBlock() instanceof BlockDoor && !MovementHelper.isDoorPassable(ctx, src, dest)
|| pb1.getBlock() instanceof BlockDoor && !MovementHelper.isDoorPassable(ctx, dest, src))
&& !(Blocks.IRON_DOOR.equals(pb0.getBlock()) || Blocks.IRON_DOOR.equals(pb1.getBlock()))) {
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), positionsToBreak[0]), ctx.playerRotations()), true))
.setInput(Input.CLICK_RIGHT, true);
}
if (pb0.getBlock() instanceof BlockFenceGate || pb1.getBlock() instanceof BlockFenceGate) {
BlockPos blocked = null;
if (!MovementHelper.isGatePassable(ctx, positionsToBreak[0], src.up())) {
blocked = positionsToBreak[0];
} else if (!MovementHelper.isGatePassable(ctx, positionsToBreak[1], src)) {
blocked = positionsToBreak[1];
}
BlockPos blocked = !MovementHelper.isGatePassable(ctx, positionsToBreak[0], src.up()) ? positionsToBreak[0]
: !MovementHelper.isGatePassable(ctx, positionsToBreak[1], src) ? positionsToBreak[1]
: null;
if (blocked != null) {
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), blocked), ctx.playerRotations()), true))
.setInput(Input.CLICK_RIGHT, true);
@@ -219,17 +224,20 @@ public class MovementTraverse extends Movement {
}
boolean isTheBridgeBlockThere = MovementHelper.canWalkOn(ctx, positionToPlace) || ladder;
BlockPos whereAmI = ctx.playerFeet();
if (whereAmI.getY() != dest.getY() && !ladder) {
BlockPos feet = ctx.playerFeet();
if (feet.getY() != dest.getY() && !ladder) {
logDebug("Wrong Y coordinate");
if (whereAmI.getY() < dest.getY()) {
state.setInput(Input.JUMP, true);
if (feet.getY() < dest.getY()) {
return state.setInput(Input.JUMP, true);
}
return state;
}
if (isTheBridgeBlockThere) {
if (ctx.playerFeet().equals(dest)) {
if (feet.equals(dest)) {
return state.setStatus(MovementStatus.SUCCESS);
}
if (Baritone.settings().overshootTraverse.value && (feet.equals(dest.add(getDirection())) || feet.equals(dest.add(getDirection()).add(getDirection())))) {
return state.setStatus(MovementStatus.SUCCESS);
}
Block low = BlockStateInterface.get(ctx, src).getBlock();
@@ -240,21 +248,22 @@ public class MovementTraverse extends Movement {
return state;
}
BlockPos into = dest.subtract(src).add(dest);
Block intoBelow = BlockStateInterface.get(ctx, into).getBlock();
Block intoAbove = BlockStateInterface.get(ctx, into.up()).getBlock();
if (wasTheBridgeBlockAlwaysThere && (!MovementHelper.isLiquid(ctx, ctx.playerFeet()) || Baritone.settings().sprintInWater.value) && (!MovementHelper.avoidWalkingInto(intoBelow) || MovementHelper.isWater(intoBelow)) && !MovementHelper.avoidWalkingInto(intoAbove)) {
IBlockState intoBelow = BlockStateInterface.get(ctx, into);
IBlockState intoAbove = BlockStateInterface.get(ctx, into.up());
if (wasTheBridgeBlockAlwaysThere && (!MovementHelper.isLiquid(ctx, feet) || Baritone.settings().sprintInWater.value) && (!MovementHelper.avoidWalkingInto(intoBelow) || MovementHelper.isWater(intoBelow)) && !MovementHelper.avoidWalkingInto(intoAbove)) {
state.setInput(Input.SPRINT, true);
}
Block destDown = BlockStateInterface.get(ctx, dest.down()).getBlock();
if (whereAmI.getY() != dest.getY() && ladder && (destDown == Blocks.VINE || destDown == Blocks.LADDER)) {
new MovementPillar(baritone, dest.down(), dest).updateState(state); // i'm sorry
return state;
IBlockState destDown = BlockStateInterface.get(ctx, dest.down());
BlockPos against = positionsToBreak[0];
if (feet.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.get(BlockLadder.FACING).getOpposite());
}
MovementHelper.moveTowards(ctx, state, positionsToBreak[0]);
MovementHelper.moveTowards(ctx, state, against);
return state;
} else {
wasTheBridgeBlockAlwaysThere = false;
Block standingOn = BlockStateInterface.get(ctx, ctx.playerFeet().down()).getBlock();
Block standingOn = BlockStateInterface.get(ctx, feet.down()).getBlock();
if (standingOn.equals(Blocks.SOUL_SAND) || standingOn instanceof BlockSlab) { // see issue #118
double dist = Math.max(Math.abs(dest.getX() + 0.5 - ctx.player().posX), Math.abs(dest.getZ() + 0.5 - ctx.player().posZ));
if (dist < 0.85) { // 0.5 + 0.3 + epsilon
@@ -292,7 +301,7 @@ public class MovementTraverse extends Movement {
default:
break;
}
if (whereAmI.equals(dest)) {
if (feet.equals(dest)) {
// If we are in the block that we are trying to get to, we are sneaking over air and we need to place a block beneath us against the one we just walked off of
// Out.log(from + " " + to + " " + faceX + "," + faceY + "," + faceZ + " " + whereAmI);
double faceX = (dest.getX() + src.getX() + 1.0D) * 0.5D;
@@ -311,7 +320,7 @@ public class MovementTraverse extends Movement {
} else {
state.setTarget(new MovementState.MovementTarget(backToFace, true));
}
if (Objects.equals(ctx.getSelectedBlock().orElse(null), goalLook)) {
if (ctx.isLookingAt(goalLook)) {
return state.setInput(Input.CLICK_RIGHT, true); // wait to right click until we are able to place
}
// Out.log("Trying to look at " + goalLook + ", actually looking at" + Baritone.whatAreYouLookingAt());

View File

@@ -23,10 +23,7 @@ import baritone.api.pathing.movement.ActionCosts;
import baritone.api.pathing.movement.IMovement;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.pathing.path.IPathExecutor;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.IPlayerContext;
import baritone.api.utils.RotationUtils;
import baritone.api.utils.VecUtils;
import baritone.api.utils.*;
import baritone.api.utils.input.Input;
import baritone.behavior.PathingBehavior;
import baritone.pathing.calc.AbstractNodeCostSearch;
@@ -35,9 +32,6 @@ import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.movements.*;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import net.minecraft.block.BlockLiquid;
import net.minecraft.init.Blocks;
import net.minecraft.util.Tuple;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
@@ -104,14 +98,13 @@ public class PathExecutor implements IPathExecutor, Helper {
if (pathPosition >= path.length()) {
return true; // stop bugging me, I'm done
}
BetterBlockPos whereShouldIBe = path.positions().get(pathPosition);
Movement movement = (Movement) path.movements().get(pathPosition);
BetterBlockPos whereAmI = ctx.playerFeet();
if (!whereShouldIBe.equals(whereAmI) && !Blocks.AIR.equals(BlockStateInterface.getBlock(ctx, whereAmI.down()))) {//do not skip if standing on air, because our position isn't stable to skip
for (int i = 0; i < pathPosition - 1 && i < path.length(); i++) {//this happens for example when you lag out and get teleported back a couple blocks
if (whereAmI.equals(path.positions().get(i))) {
logDebug("Skipping back " + (pathPosition - i) + " steps, to " + i);
if (!movement.getValidPositions().contains(whereAmI)) {
for (int i = 0; i < pathPosition && i < path.length(); i++) {//this happens for example when you lag out and get teleported back a couple blocks
if (((Movement) path.movements().get(i)).getValidPositions().contains(whereAmI)) {
int previousPos = pathPosition;
pathPosition = Math.max(i - 1, 0); // previous step might not actually be done
pathPosition = i;
for (int j = pathPosition; j <= previousPos; j++) {
path.movements().get(j).reset();
}
@@ -120,9 +113,9 @@ public class PathExecutor implements IPathExecutor, Helper {
return false;
}
}
for (int i = pathPosition + 3; i < path.length(); i++) { //dont check pathPosition+1. the movement tells us when it's done (e.g. sneak placing)
for (int i = pathPosition + 3; i < path.length() - 1; i++) { //dont check pathPosition+1. the movement tells us when it's done (e.g. sneak placing)
// also don't check pathPosition+2 because reasons
if (whereAmI.equals(path.positions().get(i))) {
if (((Movement) path.movements().get(i)).getValidPositions().contains(whereAmI)) {
if (i - pathPosition > 2) {
logDebug("Skipping forward " + (i - pathPosition) + " steps, to " + i);
}
@@ -137,7 +130,7 @@ public class PathExecutor implements IPathExecutor, Helper {
Tuple<Double, BlockPos> status = closestPathPos(path);
if (possiblyOffPath(status, MAX_DIST_FROM_PATH)) {
ticksAway++;
System.out.println("FAR AWAY FROM PATH FOR " + ticksAway + " TICKS. Current distance: " + status.getFirst() + ". Threshold: " + MAX_DIST_FROM_PATH);
System.out.println("FAR AWAY FROM PATH FOR " + ticksAway + " TICKS. Current distance: " + status.getA() + ". Threshold: " + MAX_DIST_FROM_PATH);
if (ticksAway > MAX_TICKS_AWAY) {
logDebug("Too far away from path for too long, cancelling path");
cancel();
@@ -151,38 +144,6 @@ public class PathExecutor implements IPathExecutor, Helper {
cancel();
return false;
}
//this commented block is literally cursed.
/*Out.log(actions.get(pathPosition));
if (pathPosition < actions.size() - 1) {//if there are two ActionBridges in a row and they are at right angles, walk diagonally. This makes it so you walk at 45 degrees along a zigzag path instead of doing inefficient zigging and zagging
if ((actions.get(pathPosition) instanceof ActionBridge) && (actions.get(pathPosition + 1) instanceof ActionBridge)) {
ActionBridge curr = (ActionBridge) actions.get(pathPosition);
ActionBridge next = (ActionBridge) actions.get(pathPosition + 1);
if (curr.dx() != next.dx() || curr.dz() != next.dz()) {//two movement are not parallel, so this is a right angle
if (curr.amIGood() && next.amIGood()) {//nothing in the way
BlockPos cornerToCut1 = new BlockPos(next.to.getX() - next.from.getX() + curr.from.getX(), next.to.getY(), next.to.getZ() - next.from.getZ() + curr.from.getZ());
BlockPos cornerToCut2 = cornerToCut1.up();
//Block corner1 = Baritone.get(cornerToCut1).getBlock();
//Block corner2 = Baritone.get(cornerToCut2).getBlock();
//Out.gui("Cutting conner " + cornerToCut1 + " " + corner1, Out.Mode.Debug);
if (!Action.avoidWalkingInto(cornerToCut1) && !Action.avoidWalkingInto(cornerToCut2)) {
double x = (next.from.getX() + next.to.getX() + 1.0D) * 0.5D;
double z = (next.from.getZ() + next.to.getZ() + 1.0D) * 0.5D;
MovementManager.clearMovement();
if (!MovementManager.forward && curr.oneInTen != null && curr.oneInTen) {
MovementManager.clearMovement();
MovementManager.forward = LookManager.lookAtCoords(x, 0, z, false);
} else {
MovementManager.moveTowardsCoords(x, 0, z);
}
if (MovementManager.forward && !MovementManager.backward) {
thePlayer.setSprinting(true);
}
return false;
}
}
}
}
}*/
//long start = System.nanoTime() / 1000000L;
BlockStateInterface bsi = new BlockStateInterface(ctx);
for (int i = pathPosition - 10; i < pathPosition + 10; i++) {
@@ -209,10 +170,10 @@ public class PathExecutor implements IPathExecutor, Helper {
HashSet<BlockPos> newPlace = new HashSet<>();
HashSet<BlockPos> newWalkInto = new HashSet<>();
for (int i = pathPosition; i < path.movements().size(); i++) {
Movement movement = (Movement) path.movements().get(i);
newBreak.addAll(movement.toBreak(bsi));
newPlace.addAll(movement.toPlace(bsi));
newWalkInto.addAll(movement.toWalkInto(bsi));
Movement m = (Movement) path.movements().get(i);
newBreak.addAll(m.toBreak(bsi));
newPlace.addAll(m.toPlace(bsi));
newWalkInto.addAll(m.toWalkInto(bsi));
}
toBreak = newBreak;
toPlace = newPlace;
@@ -223,7 +184,14 @@ public class PathExecutor implements IPathExecutor, Helper {
if (end - start > 0) {
System.out.println("Recalculating break and place took " + (end - start) + "ms");
}*/
IMovement movement = path.movements().get(pathPosition);
if (pathPosition < path.movements().size() - 1) {
IMovement next = path.movements().get(pathPosition + 1);
if (!behavior.baritone.bsi.worldContainsLoadedChunk(next.getDest().x, next.getDest().z)) {
logDebug("Pausing since destination is at edge of loaded chunks");
clearKeys();
return true;
}
}
boolean canCancel = movement.safeToCancel();
if (costEstimateIndex == null || costEstimateIndex != pathPosition) {
costEstimateIndex = pathPosition;
@@ -237,7 +205,7 @@ public class PathExecutor implements IPathExecutor, Helper {
}
}
}
double currentCost = ((Movement) movement).recalculateCost(behavior.secretInternalGetCalculationContext());
double currentCost = movement.recalculateCost(behavior.secretInternalGetCalculationContext());
if (currentCost >= ActionCosts.COST_INF && canCancel) {
logDebug("Something has changed in the world and this movement has become impossible. Cancelling.");
cancel();
@@ -289,11 +257,13 @@ public class PathExecutor implements IPathExecutor, Helper {
private Tuple<Double, BlockPos> closestPathPos(IPath path) {
double best = -1;
BlockPos bestPos = null;
for (BlockPos pos : path.positions()) {
double dist = VecUtils.entityDistanceToCenter(ctx.player(), pos);
if (dist < best || best == -1) {
best = dist;
bestPos = pos;
for (IMovement movement : path.movements()) {
for (BlockPos pos : ((Movement) movement).getValidPositions()) {
double dist = VecUtils.entityDistanceToCenter(ctx.player(), pos);
if (dist < best || best == -1) {
best = dist;
bestPos = pos;
}
}
}
return new Tuple<>(best, bestPos);
@@ -333,7 +303,7 @@ public class PathExecutor implements IPathExecutor, Helper {
}
private boolean possiblyOffPath(Tuple<Double, BlockPos> status, double leniency) {
double distanceFromPath = status.getFirst();
double distanceFromPath = status.getA();
if (distanceFromPath > leniency) {
// when we're midair in the middle of a fall, we're very far from both the beginning and the end, but we aren't actually off path
if (path.movements().get(pathPosition) instanceof MovementFall) {
@@ -353,7 +323,7 @@ public class PathExecutor implements IPathExecutor, Helper {
* @return Whether or not it was possible to snap to the current player feet
*/
public boolean snipsnapifpossible() {
if (!ctx.player().onGround && !(ctx.world().getBlockState(ctx.playerFeet()).getBlock() instanceof BlockLiquid)) {
if (!ctx.player().onGround && ctx.world().getFluidState(ctx.playerFeet()).isEmpty()) {
// if we're falling in the air, and not in water, don't splice
return false;
} else {
@@ -441,7 +411,10 @@ public class PathExecutor implements IPathExecutor, Helper {
IMovement prev = path.movements().get(pathPosition - 1);
if (prev instanceof MovementDescend && prev.getDirection().up().equals(current.getDirection().down())) {
BlockPos center = current.getSrc().up();
if (ctx.player().posY >= center.getY()) { // playerFeet adds 0.1251 to account for soul sand
// playerFeet adds 0.1251 to account for soul sand
// farmland is 0.9375
// 0.07 is to account for farmland
if (ctx.player().posY >= center.getY() - 0.07) {
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.JUMP, false);
return true;
}
@@ -453,7 +426,7 @@ public class PathExecutor implements IPathExecutor, Helper {
if (current instanceof MovementFall) {
Tuple<Vec3d, BlockPos> data = overrideFall((MovementFall) current);
if (data != null) {
BlockPos fallDest = data.getSecond();
BetterBlockPos fallDest = new BetterBlockPos(data.getB());
if (!path.positions().contains(fallDest)) {
throw new IllegalStateException();
}
@@ -464,7 +437,7 @@ public class PathExecutor implements IPathExecutor, Helper {
return true;
}
clearKeys();
behavior.baritone.getLookBehavior().updateTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), data.getFirst(), ctx.playerRotations()), false);
behavior.baritone.getLookBehavior().updateTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), data.getA(), ctx.playerRotations()), false);
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.MOVE_FORWARD, true);
return true;
}
@@ -556,17 +529,20 @@ public class PathExecutor implements IPathExecutor, Helper {
}
}
}
if (MovementHelper.avoidWalkingInto(ctx.world().getBlockState(current.getSrc().up(3)).getBlock())) {
if (MovementHelper.avoidWalkingInto(ctx.world().getBlockState(current.getSrc().up(3)))) {
return false;
}
return !MovementHelper.avoidWalkingInto(ctx.world().getBlockState(next.getDest().up(2)).getBlock()); // codacy smh my head
return !MovementHelper.avoidWalkingInto(ctx.world().getBlockState(next.getDest().up(2))); // codacy smh my head
}
private static boolean canSprintFromDescendInto(IPlayerContext ctx, IMovement current, IMovement next) {
if (next instanceof MovementDescend && next.getDirection().equals(current.getDirection())) {
return true;
}
if (next instanceof MovementTraverse && next.getDirection().down().equals(current.getDirection()) && MovementHelper.canWalkOn(ctx, next.getDest().down())) {
if (!MovementHelper.canWalkOn(ctx, current.getDest().add(current.getDirection()))) {
return false;
}
if (next instanceof MovementTraverse && next.getDirection().down().equals(current.getDirection())) {
return true;
}
return next instanceof MovementDiagonal && Baritone.settings().allowOvershootDiagonalDescend.value;
@@ -608,7 +584,7 @@ public class PathExecutor implements IPathExecutor, Helper {
ret.costEstimateIndex = costEstimateIndex;
ret.ticksOnCurrent = ticksOnCurrent;
return ret;
}).orElse(cutIfTooLong());
}).orElseGet(this::cutIfTooLong); // dont actually call cutIfTooLong every tick if we won't actually use it, use a method reference
}
private PathExecutor cutIfTooLong() {

View File

@@ -0,0 +1,142 @@
/*
* 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.math.BlockPos;
import net.minecraft.world.chunk.EmptyChunk;
import java.util.*;
import java.util.stream.Collectors;
public final 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);
default:
throw new IllegalStateException();
}
}
return new PathingCommand(null, PathingCommandType.DEFER); // cede to other process
}
private 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 -> baritone.getBuilderProcess().placementPlausible(pos, Blocks.DIRT.getDefaultState()))
.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;
}
}

View File

@@ -35,48 +35,62 @@ import baritone.utils.BlockStateInterface;
import baritone.utils.PathingCommandContext;
import baritone.utils.schematic.AirSchematic;
import baritone.utils.schematic.Schematic;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import net.minecraft.block.BlockAir;
import net.minecraft.block.BlockFlowingFluid;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.init.Blocks;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Tuple;
import net.minecraft.util.math.*;
import net.minecraft.util.math.shapes.VoxelShape;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
import static baritone.api.pathing.movement.ActionCosts.COST_INF;
public class BuilderProcess extends BaritoneProcessHelper implements IBuilderProcess {
public BuilderProcess(Baritone baritone) {
super(baritone);
}
public final class BuilderProcess extends BaritoneProcessHelper implements IBuilderProcess {
private HashSet<BetterBlockPos> incorrectPositions;
private LongOpenHashSet observedCompleted; // positions that are completed even if they're out of render distance and we can't make sure right now
private String name;
private ISchematic realSchematic;
private ISchematic schematic;
private Vec3i origin;
private int ticks;
private boolean paused;
private int layer;
public boolean build(String schematicFile, BlockPos origin) {
File file = new File(new File(Minecraft.getMinecraft().gameDir, "schematics"), schematicFile);
System.out.println(file + " " + file.exists());
return build(schematicFile, file, origin);
public BuilderProcess(Baritone baritone) {
super(baritone);
}
@Override
public void build(String name, ISchematic schematic, Vec3i origin) {
this.name = name;
this.schematic = schematic;
this.realSchematic = null;
this.origin = origin;
this.paused = false;
this.layer = 0;
this.observedCompleted = new LongOpenHashSet();
}
public void resume() {
paused = false;
}
public void pause() {
paused = true;
}
@Override
@@ -120,27 +134,30 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
return null;
}
IBlockState state = schematic.desiredState(x - origin.getX(), y - origin.getY(), z - origin.getZ());
if (state.getBlock() == Blocks.AIR) {
if (state.getBlock() instanceof BlockAir) {
return null;
}
return state;
}
public Optional<Tuple<BetterBlockPos, Rotation>> toBreakNearPlayer(BuilderCalculationContext bcc) {
private Optional<Tuple<BetterBlockPos, Rotation>> toBreakNearPlayer(BuilderCalculationContext bcc) {
BetterBlockPos center = ctx.playerFeet();
BetterBlockPos pathStart = baritone.getPathingBehavior().pathStart();
for (int dx = -5; dx <= 5; dx++) {
for (int dy = 0; dy <= 5; dy++) {
for (int dy = Baritone.settings().breakFromAbove.value ? -1 : 0; dy <= 5; dy++) {
for (int dz = -5; dz <= 5; dz++) {
int x = center.x + dx;
int y = center.y + dy;
int z = center.z + dz;
if (dy == -1 && x == pathStart.x && z == pathStart.z) {
continue; // dont mine what we're supported by, but not directly standing on
}
IBlockState desired = bcc.getSchematic(x, y, z);
if (desired == null) {
continue; // irrelevant
}
IBlockState curr = bcc.bsi.get0(x, y, z);
if (curr.getBlock() != Blocks.AIR && !valid(curr, desired)) {
if (!(curr.getBlock() instanceof BlockAir) && !(curr.getBlock() == Blocks.WATER || curr.getBlock() == Blocks.LAVA) && !valid(curr, desired)) {
BetterBlockPos pos = new BetterBlockPos(x, y, z);
Optional<Rotation> rot = RotationUtils.reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance());
if (rot.isPresent()) {
@@ -154,10 +171,10 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
}
public class Placement {
final int hotbarSelection;
final BlockPos placeAgainst;
final EnumFacing side;
final Rotation rot;
private final int hotbarSelection;
private final BlockPos placeAgainst;
private final EnumFacing side;
private final Rotation rot;
public Placement(int hotbarSelection, BlockPos placeAgainst, EnumFacing side, Rotation rot) {
this.hotbarSelection = hotbarSelection;
@@ -167,7 +184,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
}
}
public Optional<Placement> searchForPlacables(BuilderCalculationContext bcc, List<IBlockState> desirableOnHotbar) {
private Optional<Placement> searchForPlacables(BuilderCalculationContext bcc, List<IBlockState> desirableOnHotbar) {
BetterBlockPos center = ctx.playerFeet();
for (int dx = -5; dx <= 5; dx++) {
for (int dy = -5; dy <= 1; dy++) {
@@ -181,7 +198,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
}
IBlockState curr = bcc.bsi.get0(x, y, z);
if (MovementHelper.isReplacable(x, y, z, curr, bcc.bsi) && !valid(curr, desired)) {
if (dy == 1 && bcc.bsi.get0(x, y + 1, z).getBlock() == Blocks.AIR) {
if (dy == 1 && bcc.bsi.get0(x, y + 1, z).getBlock() instanceof BlockAir) {
continue;
}
desirableOnHotbar.add(desired);
@@ -196,24 +213,32 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
return Optional.empty();
}
public Optional<Placement> possibleToPlace(IBlockState toPlace, int x, int y, int z, BlockStateInterface bsi) {
public boolean placementPlausible(BlockPos pos, IBlockState state) {
VoxelShape voxelshape = state.getCollisionShape(ctx.world(), pos);
return voxelshape.isEmpty() || ctx.world().checkNoEntityCollision(null, voxelshape.withOffset(pos.getX(), pos.getY(), pos.getZ()));
}
private Optional<Placement> possibleToPlace(IBlockState toPlace, int x, int y, int z, BlockStateInterface bsi) {
for (EnumFacing against : EnumFacing.values()) {
BetterBlockPos placeAgainstPos = new BetterBlockPos(x, y, z).offset(against);
IBlockState placeAgainstState = bsi.get0(placeAgainstPos);
if (MovementHelper.isReplacable(placeAgainstPos.x, placeAgainstPos.y, placeAgainstPos.z, placeAgainstState, bsi)) {
continue;
}
if (!ctx.world().mayPlace(toPlace.getBlock(), new BetterBlockPos(x, y, z), false, against, null)) {
if (!toPlace.isValidPosition(ctx.world(), new BetterBlockPos(x, y, z))) {
continue;
}
AxisAlignedBB aabb = placeAgainstState.getBoundingBox(ctx.world(), placeAgainstPos);
if (!placementPlausible(new BetterBlockPos(x, y, z), toPlace)) {
continue;
}
AxisAlignedBB aabb = placeAgainstState.getShape(ctx.world(), placeAgainstPos).getBoundingBox();
for (Vec3d placementMultiplier : aabbSideMultipliers(against)) {
double placeX = placeAgainstPos.x + aabb.minX * placementMultiplier.x + aabb.maxX * (1 - placementMultiplier.x);
double placeY = placeAgainstPos.y + aabb.minY * placementMultiplier.y + aabb.maxY * (1 - placementMultiplier.y);
double placeZ = placeAgainstPos.z + aabb.minZ * placementMultiplier.z + aabb.maxZ * (1 - placementMultiplier.z);
Rotation rot = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(placeX, placeY, placeZ), ctx.playerRotations());
RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot, ctx.playerController().getBlockReachDistance());
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK && result.getBlockPos().equals(placeAgainstPos) && result.sideHit == against.getOpposite()) {
if (result != null && result.type == RayTraceResult.Type.BLOCK && result.getBlockPos().equals(placeAgainstPos) && result.sideHit == against.getOpposite()) {
OptionalInt hotbar = hasAnyItemThatWouldPlace(toPlace, result, rot);
if (hotbar.isPresent()) {
return Optional.of(new Placement(hotbar.getAsInt(), placeAgainstPos, against.getOpposite(), rot));
@@ -224,8 +249,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
return Optional.empty();
}
public OptionalInt hasAnyItemThatWouldPlace(IBlockState desired, RayTraceResult result, Rotation rot) {
private OptionalInt hasAnyItemThatWouldPlace(IBlockState desired, RayTraceResult result, Rotation rot) {
for (int i = 0; i < 9; i++) {
ItemStack stack = ctx.player().inventory.mainInventory.get(i);
if (stack.isEmpty() || !(stack.getItem() instanceof ItemBlock)) {
@@ -236,18 +260,24 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
// the state depends on the facing of the player sometimes
ctx.player().rotationYaw = rot.getYaw();
ctx.player().rotationPitch = rot.getPitch();
IBlockState wouldBePlaced = ((ItemBlock) stack.getItem()).getBlock().getStateForPlacement(
ctx.world(),
BlockItemUseContext meme = new BlockItemUseContext(new ItemUseContext(
ctx.player(),
stack,
result.getBlockPos().offset(result.sideHit),
result.sideHit,
(float) result.hitVec.x - result.getBlockPos().getX(), // as in PlayerControllerMP
(float) result.hitVec.x - result.getBlockPos().getX(),
(float) result.hitVec.y - result.getBlockPos().getY(),
(float) result.hitVec.z - result.getBlockPos().getZ(),
stack.getItem().getMetadata(stack.getMetadata()),
ctx.player()
);
(float) result.hitVec.z - result.getBlockPos().getZ()
));
IBlockState wouldBePlaced = ((ItemBlock) stack.getItem()).getBlock().getStateForPlacement(meme);
ctx.player().rotationYaw = originalYaw;
ctx.player().rotationPitch = originalPitch;
if (wouldBePlaced == null) {
continue;
}
if (!meme.canPlace()) {
continue;
}
if (valid(wouldBePlaced, desired)) {
return OptionalInt.of(i);
}
@@ -269,39 +299,91 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
double z = side.getZOffset() == 0 ? 0.5 : (1 + side.getZOffset()) / 2D;
return new Vec3d[]{new Vec3d(x, 0.25, z), new Vec3d(x, 0.75, z)};
default: // null
throw new NullPointerException();
throw new IllegalStateException();
}
}
@Override
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
// TODO somehow tell inventorybehavior what we'd like to have on the hotbar
// perhaps take the 16 closest positions in incorrectPositions to ctx.playerFeet that aren't desired to be air, and then snag the top 4 most common block states, then request those on the hotbar
// this will work as is, but it'll be trashy
// need to iterate over incorrectPositions and see which ones we can "correct" from our current standing position
baritone.getInputOverrideHandler().clearAllKeys();
BuilderCalculationContext bcc = new BuilderCalculationContext();
if (!recalc(bcc)) {
logDirect("Done building");
onLostControl();
return null;
}
trim(bcc);
if (baritone.getInputOverrideHandler().isInputForcedDown(Input.CLICK_LEFT)) {
ticks = 5;
} else {
ticks--;
}
Optional<Tuple<BetterBlockPos, Rotation>> toBreak = toBreakNearPlayer(bcc);
baritone.getInputOverrideHandler().clearAllKeys();
if (paused) {
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
}
if (Baritone.settings().buildInLayers.value) {
if (realSchematic == null) {
realSchematic = schematic;
}
ISchematic realSchematic = this.realSchematic; // wrap this properly, dont just have the inner class refer to the builderprocess.this
int minYInclusive;
int maxYInclusive;
// layer = 0 should be nothing
// layer = realSchematic.heightY() should be everything
if (Baritone.settings().layerOrder.value) { // top to bottom
maxYInclusive = realSchematic.heightY() - 1;
minYInclusive = realSchematic.heightY() - layer;
} else {
maxYInclusive = layer - 1;
minYInclusive = 0;
}
schematic = new ISchematic() {
@Override
public IBlockState desiredState(int x, int y, int z) {
return realSchematic.desiredState(x, y, z);
}
@Override
public boolean inSchematic(int x, int y, int z) {
return ISchematic.super.inSchematic(x, y, z) && y >= minYInclusive && y <= maxYInclusive;
}
@Override
public int widthX() {
return realSchematic.widthX();
}
@Override
public int heightY() {
return realSchematic.heightY();
}
@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);
}
Vec3i repeat = Baritone.settings().buildRepeat.value;
if (repeat.equals(new Vec3i(0, 0, 0))) {
logDirect("Done building");
onLostControl();
return null;
}
// build repeat time
layer = 0;
origin = new BlockPos(origin).add(repeat);
logDirect("Repeating build in vector " + repeat + ", new origin is " + origin);
return onTick(calcFailed, isSafeToCancel);
}
trim();
Optional<Tuple<BetterBlockPos, Rotation>> toBreak = toBreakNearPlayer(bcc);
if (toBreak.isPresent() && isSafeToCancel && ctx.player().onGround) {
// we'd like to pause to break this block
// only change look direction if it's safe (don't want to fuck up an in progress parkour for example
Rotation rot = toBreak.get().getSecond();
BetterBlockPos pos = toBreak.get().getFirst();
Rotation rot = toBreak.get().getB();
BetterBlockPos pos = toBreak.get().getA();
baritone.getLookBehavior().updateTarget(rot, true);
MovementHelper.switchToBestToolFor(ctx, bcc.get(pos));
if (ctx.player().isSneaking()) {
@@ -310,10 +392,10 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
// and is unable since it's unsneaked in the intermediary tick
baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, true);
}
if (Objects.equals(ctx.objectMouseOver().getBlockPos(), pos) || ctx.playerRotations().isReallyCloseTo(rot)) {
if (ctx.isLookingAt(pos) || ctx.playerRotations().isReallyCloseTo(rot)) {
baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_LEFT, true);
}
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
}
List<IBlockState> desirableOnHotbar = new ArrayList<>();
Optional<Placement> toPlace = searchForPlacables(bcc, desirableOnHotbar);
@@ -322,10 +404,10 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
baritone.getLookBehavior().updateTarget(rot, true);
ctx.player().inventory.currentItem = toPlace.get().hotbarSelection;
baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, true);
if ((Objects.equals(ctx.objectMouseOver().getBlockPos(), toPlace.get().placeAgainst) && ctx.objectMouseOver().sideHit.equals(toPlace.get().side)) || ctx.playerRotations().isReallyCloseTo(rot)) {
if ((ctx.isLookingAt(toPlace.get().placeAgainst) && ctx.objectMouseOver().sideHit.equals(toPlace.get().side)) || ctx.playerRotations().isReallyCloseTo(rot)) {
baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true);
}
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
}
List<IBlockState> approxPlacable = placable(36);
@@ -359,15 +441,15 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
if (goal == null) {
goal = assemble(bcc, approxPlacable); // we're far away, so assume that we have our whole inventory to recalculate placable properly
if (goal == null) {
logDirect("Unable to do it =(");
onLostControl();
return null;
logDirect("Unable to do it. Pausing. resume to resume, cancel to cancel");
paused = true;
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
}
}
return new PathingCommandContext(goal, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH, bcc);
}
public boolean recalc(BuilderCalculationContext bcc) {
private boolean recalc(BuilderCalculationContext bcc) {
if (incorrectPositions == null) {
incorrectPositions = new HashSet<>();
fullRecalc(bcc);
@@ -382,7 +464,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
return !incorrectPositions.isEmpty();
}
public void trim(BuilderCalculationContext bcc) {
private void trim() {
HashSet<BetterBlockPos> copy = new HashSet<>(incorrectPositions);
copy.removeIf(pos -> pos.distanceSq(ctx.player().posX, ctx.player().posY, ctx.player().posZ) > 200);
if (!copy.isEmpty()) {
@@ -390,7 +472,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
}
}
public void recalcNearby(BuilderCalculationContext bcc) {
private void recalcNearby(BuilderCalculationContext bcc) {
BetterBlockPos center = ctx.playerFeet();
for (int dx = -5; dx <= 5; dx++) {
for (int dy = -5; dy <= 5; dy++) {
@@ -401,10 +483,13 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
IBlockState desired = bcc.getSchematic(x, y, z);
if (desired != null) {
// we care about this position
BetterBlockPos pos = new BetterBlockPos(x, y, z);
if (valid(bcc.bsi.get0(x, y, z), desired)) {
incorrectPositions.remove(new BetterBlockPos(x, y, z));
incorrectPositions.remove(pos);
observedCompleted.add(BetterBlockPos.longHash(pos));
} else {
incorrectPositions.add(new BetterBlockPos(x, y, z));
incorrectPositions.add(pos);
observedCompleted.remove(BetterBlockPos.longHash(pos));
}
}
}
@@ -412,15 +497,32 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
}
}
public void fullRecalc(BuilderCalculationContext bcc) {
private void fullRecalc(BuilderCalculationContext bcc) {
incorrectPositions = new HashSet<>();
for (int y = 0; y < schematic.heightY(); y++) {
for (int z = 0; z < schematic.lengthZ(); z++) {
for (int x = 0; x < schematic.widthX(); x++) {
if (schematic.inSchematic(x, y, z)) {
if (!valid(bcc.bsi.get0(x + origin.getX(), y + origin.getY(), z + origin.getZ()), schematic.desiredState(x, y, z))) {
incorrectPositions.add(new BetterBlockPos(x + origin.getX(), y + origin.getY(), z + origin.getZ()));
if (!schematic.inSchematic(x, y, z)) {
continue;
}
int blockX = x + origin.getX();
int blockY = y + origin.getY();
int blockZ = z + origin.getZ();
if (bcc.bsi.worldContainsLoadedChunk(blockX, blockZ)) { // check if its in render distance, not if its in cache
// we can directly observe this block, it is in render distance
if (valid(bcc.bsi.get0(blockX, blockY, blockZ), schematic.desiredState(x, y, z))) {
observedCompleted.add(BetterBlockPos.longHash(blockX, blockY, blockZ));
} else {
incorrectPositions.add(new BetterBlockPos(blockX, blockY, blockZ));
observedCompleted.remove(BetterBlockPos.longHash(blockX, blockY, blockZ));
}
continue;
}
// this is not in render distance
if (!observedCompleted.contains(BetterBlockPos.longHash(blockX, blockY, blockZ))) {
// and we've never seen this position be correct
// therefore mark as incorrect
incorrectPositions.add(new BetterBlockPos(blockX, blockY, blockZ));
}
}
}
@@ -428,17 +530,45 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
}
private Goal assemble(BuilderCalculationContext bcc, List<IBlockState> approxPlacable) {
List<BetterBlockPos> placable = incorrectPositions.stream().filter(pos -> bcc.bsi.get0(pos).getBlock() == Blocks.AIR && approxPlacable.contains(bcc.getSchematic(pos.x, pos.y, pos.z))).collect(Collectors.toList());
Goal[] toBreak = incorrectPositions.stream().filter(pos -> bcc.bsi.get0(pos).getBlock() != Blocks.AIR).map(GoalBreak::new).toArray(Goal[]::new);
Goal[] toPlace = placable.stream().filter(pos -> !placable.contains(pos.down()) && !placable.contains(pos.down(2))).map(pos -> placementgoal(pos, bcc)).toArray(Goal[]::new);
List<BetterBlockPos> placable = new ArrayList<>();
List<BetterBlockPos> breakable = new ArrayList<>();
List<BetterBlockPos> sourceLiquids = new ArrayList<>();
incorrectPositions.forEach(pos -> {
IBlockState state = bcc.bsi.get0(pos);
if (state.getBlock() instanceof BlockAir) {
if (approxPlacable.contains(bcc.getSchematic(pos.x, pos.y, pos.z))) {
placable.add(pos);
}
} else {
if (state.getBlock() instanceof BlockFlowingFluid) {
// if the block itself is JUST a liquid (i.e. not just a waterlogged block), we CANNOT break it
// TODO for 1.13 make sure that this only matches pure water, not waterlogged blocks
if (!MovementHelper.possiblyFlowing(state)) {
// if it's a source block then we want to replace it with a throwaway
sourceLiquids.add(pos);
}
} else {
breakable.add(pos);
}
}
});
List<Goal> toBreak = new ArrayList<>();
breakable.forEach(pos -> toBreak.add(breakGoal(pos, bcc)));
List<Goal> toPlace = new ArrayList<>();
placable.forEach(pos -> {
if (!placable.contains(pos.down()) && !placable.contains(pos.down(2))) {
toPlace.add(placementGoal(pos, bcc));
}
});
sourceLiquids.forEach(pos -> toPlace.add(new GoalBlock(pos.up())));
if (toPlace.length != 0) {
return new JankyGoalComposite(new GoalComposite(toPlace), new GoalComposite(toBreak));
if (!toPlace.isEmpty()) {
return new JankyGoalComposite(new GoalComposite(toPlace.toArray(new Goal[0])), new GoalComposite(toBreak.toArray(new Goal[0])));
}
if (toBreak.length == 0) {
if (toBreak.isEmpty()) {
return null;
}
return new GoalComposite(toBreak);
return new GoalComposite(toBreak.toArray(new Goal[0]));
}
public static class JankyGoalComposite implements Goal {
@@ -484,21 +614,36 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
}
}
public Goal placementgoal(BlockPos pos, BuilderCalculationContext bcc) {
if (ctx.world().getBlockState(pos).getBlock() != Blocks.AIR) {
private Goal placementGoal(BlockPos pos, BuilderCalculationContext bcc) {
if (!(ctx.world().getBlockState(pos).getBlock() instanceof BlockAir)) { // TODO can this even happen?
return new GoalPlace(pos);
}
boolean allowSameLevel = ctx.world().getBlockState(pos.up()).getBlock() != Blocks.AIR;
for (EnumFacing facing : Movement.HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP) {
if (MovementHelper.canPlaceAgainst(ctx, pos.offset(facing)) && ctx.world().mayPlace(bcc.getSchematic(pos.getX(), pos.getY(), pos.getZ()).getBlock(), pos, false, facing, null)) {
boolean allowSameLevel = !(ctx.world().getBlockState(pos.up()).getBlock() instanceof BlockAir);
for (EnumFacing facing : Movement.HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP) {
if (MovementHelper.canPlaceAgainst(ctx, pos.offset(facing)) && placementPlausible(pos, bcc.getSchematic(pos.getX(), pos.getY(), pos.getZ()))) {
return new GoalAdjacent(pos, allowSameLevel);
}
}
return new GoalPlace(pos);
}
private Goal breakGoal(BlockPos pos, BuilderCalculationContext bcc) {
if (Baritone.settings().goalBreakFromAbove.value && bcc.bsi.get0(pos.up()).getBlock() instanceof BlockAir && bcc.bsi.get0(pos.up(2)).getBlock() instanceof BlockAir) { // TODO maybe possible without the up(2) check?
return new JankyGoalComposite(new GoalBreak(pos), new GoalGetToBlock(pos.up()) {
@Override
public boolean isInGoal(int x, int y, int z) {
if (y > this.y || (x == this.x && y == this.y && z == this.z)) {
return false;
}
return super.isInGoal(x, y, z);
}
});
}
return new GoalBreak(pos);
}
public static class GoalAdjacent extends GoalGetToBlock {
boolean allowSameLevel;
private boolean allowSameLevel;
public GoalAdjacent(BlockPos pos, boolean allowSameLevel) {
super(pos);
@@ -540,14 +685,18 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
incorrectPositions = null;
name = null;
schematic = null;
realSchematic = null;
layer = 0;
paused = false;
observedCompleted = null;
}
@Override
public String displayName0() {
return "Building " + name;
return paused ? "Builder Paused" : "Building " + name;
}
public List<IBlockState> placable(int size) {
private List<IBlockState> placable(int size) {
List<IBlockState> result = new ArrayList<>();
for (int i = 0; i < size; i++) {
ItemStack stack = ctx.player().inventory.mainInventory.get(i);
@@ -556,15 +705,21 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
continue;
}
// <toxic cloud>
result.add(((ItemBlock) stack.getItem()).getBlock().getStateForPlacement(ctx.world(), ctx.playerFeet(), EnumFacing.UP, (float) ctx.player().posX, (float) ctx.player().posY, (float) ctx.player().posZ, stack.getItem().getMetadata(stack.getMetadata()), ctx.player()));
result.add(((ItemBlock) stack.getItem()).getBlock().getStateForPlacement(new BlockItemUseContext(new ItemUseContext(ctx.player(), stack, ctx.playerFeet(), EnumFacing.UP, (float) ctx.player().posX, (float) ctx.player().posY, (float) ctx.player().posZ))));
// </toxic cloud>
}
return result;
}
public boolean valid(IBlockState current, IBlockState desired) {
private boolean valid(IBlockState current, IBlockState desired) {
if (desired == null) {
return true;
}
if (current.getBlock() instanceof BlockAir && desired.getBlock() instanceof BlockAir) {
return true;
}
// TODO more complicated comparison logic I guess
return desired == null || current.equals(desired);
return current.equals(desired);
}
public class BuilderCalculationContext extends CalculationContext {
@@ -602,7 +757,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
IBlockState sch = getSchematic(x, y, z);
if (sch != null) {
// TODO this can return true even when allowPlace is off.... is that an issue?
if (sch.getBlock() == Blocks.AIR) {
if (sch.getBlock() instanceof BlockAir) {
// we want this to be air, but they're asking if they can place here
// this won't be a schematic block, this will be a throwaway
return placeBlockCost * 2; // we're going to have to break it eventually
@@ -635,7 +790,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
}
IBlockState sch = getSchematic(x, y, z);
if (sch != null) {
if (sch.getBlock() == Blocks.AIR) {
if (sch.getBlock() instanceof BlockAir) {
// it should be air
// regardless of current contents, we can break it
return 1;

View File

@@ -29,7 +29,7 @@ import baritone.utils.BaritoneProcessHelper;
*
* @author leijurv
*/
public class CustomGoalProcess extends BaritoneProcessHelper implements ICustomGoalProcess {
public final class CustomGoalProcess extends BaritoneProcessHelper implements ICustomGoalProcess {
/**
* The current goal
@@ -90,6 +90,9 @@ public class CustomGoalProcess extends BaritoneProcessHelper implements ICustomG
}
if (this.goal == null || (this.goal.isInGoal(ctx.playerFeet()) && this.goal.isInGoal(baritone.getPathingBehavior().pathStart()))) {
onLostControl(); // we're there xd
if (Baritone.settings().disconnectOnArrival.value) {
ctx.world().sendQuittingDisconnectingPacket();
}
return new PathingCommand(this.goal, PathingCommandType.CANCEL_AND_SET_GOAL);
}
return new PathingCommand(this.goal, PathingCommandType.SET_GOAL_AND_PATH);

View File

@@ -22,19 +22,33 @@ 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.GoalYLevel;
import baritone.api.process.IExploreProcess;
import baritone.api.process.PathingCommand;
import baritone.api.process.PathingCommandType;
import baritone.api.utils.MyChunkPos;
import baritone.cache.CachedWorld;
import baritone.utils.BaritoneProcessHelper;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
public class ExploreProcess extends BaritoneProcessHelper {
public final class ExploreProcess extends BaritoneProcessHelper implements IExploreProcess {
private BlockPos explorationOrigin;
private IChunkFilter filter;
private int distanceCompleted;
public ExploreProcess(Baritone baritone) {
super(baritone);
}
@@ -44,8 +58,25 @@ public class ExploreProcess extends BaritoneProcessHelper {
return explorationOrigin != null;
}
@Override
public void explore(int centerX, int centerZ) {
explorationOrigin = new BlockPos(centerX, 0, centerZ);
distanceCompleted = 0;
}
@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
@@ -55,45 +86,193 @@ public class ExploreProcess extends BaritoneProcessHelper {
onLostControl();
return null;
}
Goal[] closestUncached = closestUncachedChunks(explorationOrigin);
IChunkFilter filter = calcFilter();
if (!Baritone.settings().disableCompletionCheck.value && filter.countRemain() == 0) {
logDirect("Explored all chunks");
onLostControl();
return null;
}
Goal[] closestUncached = closestUncachedChunks(explorationOrigin, filter);
if (closestUncached == null) {
logDebug("awaiting region load from disk");
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
}
System.out.println("Closest uncached: " + closestUncached);
return new PathingCommand(new GoalComposite(closestUncached), PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH);
}
private Goal[] closestUncachedChunks(BlockPos center) {
private Goal[] closestUncachedChunks(BlockPos center, IChunkFilter filter) {
int chunkX = center.getX() >> 4;
int chunkZ = center.getZ() >> 4;
ICachedWorld cache = baritone.getWorldProvider().getCurrentWorld().getCachedWorld();
for (int dist = 0; ; dist++) {
List<BlockPos> centers = new ArrayList<>();
int count = Math.min(filter.countRemain(), Baritone.settings().exploreChunkSetMinimumSize.value);
List<BlockPos> centers = new ArrayList<>();
int renderDistance = Baritone.settings().worldExploringChunkOffset.value;
for (int dist = distanceCompleted; ; dist++) {
for (int dx = -dist; dx <= dist; dx++) {
for (int dz = -dist; dz <= dist; dz++) {
int trueDist = Baritone.settings().exploreUsePythagorean.value ? dx * dx + dz * dz : Math.abs(dx) + Math.abs(dz);
int zval = dist - Math.abs(dx);
for (int mult = 0; mult < 2; mult++) {
int dz = (mult * 2 - 1) * zval; // dz can be either -zval or zval
int trueDist = Math.abs(dx) + Math.abs(dz);
if (trueDist != dist) {
continue; // not considering this one just yet in our expanding search
throw new IllegalStateException();
}
int centerX = (chunkX + dx) * 16 + 8;
int centerZ = (chunkZ + dz) * 18 + 8;
if (cache.isCached(centerX, centerZ)) {
continue;
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
default:
}
if (!((CachedWorld) cache).regionLoaded(centerX, centerZ)) {
Baritone.getExecutor().execute(() -> {
((CachedWorld) cache).tryLoadFromDisk(centerX >> 9, centerZ >> 9);
});
return null; // we still need to load regions from disk in order to decide properly
int centerX = ((chunkX + dx) << 4) + 8;
int centerZ = ((chunkZ + dz) << 4) + 8;
int offset = renderDistance << 4;
if (dx < 0) {
centerX -= offset;
} else {
centerX += offset;
}
if (dz < 0) {
centerZ -= offset;
} else {
centerZ += offset;
}
centers.add(new BlockPos(centerX, 0, centerZ));
}
}
if (!centers.isEmpty()) {
return centers.stream().map(pos -> new GoalXZ(pos.getX(), pos.getZ())).toArray(Goal[]::new);
if (centers.size() >= count) {
return centers.stream().map(pos -> createGoal(pos.getX(), pos.getZ())).toArray(Goal[]::new);
}
if (centers.isEmpty()) {
// we have explored everything from 0 to dist inclusive
// next time we should start our check at dist+1
distanceCompleted = dist + 1;
}
}
}
private static Goal createGoal(int x, int z) {
if (Baritone.settings().exploreMaintainY.value == -1) {
return new GoalXZ(x, z);
}
// don't use a goalblock because we still want isInGoal to return true if X and Z are correct
// we just want to try and maintain Y on the way there, not necessarily end at that specific Y
return new GoalXZ(x, z) {
@Override
public double heuristic(int x, int y, int z) {
return super.heuristic(x, y, z) + GoalYLevel.calculate(Baritone.settings().exploreMaintainY.value, y);
}
};
}
private enum Status {
EXPLORED, NOT_EXPLORED, UNKNOWN;
}
private interface IChunkFilter {
Status isAlreadyExplored(int chunkX, int chunkZ);
int countRemain();
}
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 int countRemain() {
return Integer.MAX_VALUE;
}
}
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 int countRemain() {
if (!invert) {
// if invert is false, anything not on the list is uncached
return Integer.MAX_VALUE;
}
// but if invert is true, anything not on the list IS assumed cached
// so we are done if everything on our list is cached!
int countRemain = 0;
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
countRemain++;
if (countRemain >= Baritone.settings().exploreChunkSetMinimumSize.value) {
return countRemain;
}
}
}
return countRemain;
}
}
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 int countRemain() {
return Math.min(a.countRemain(), b.countRemain());
}
}
@@ -104,6 +283,6 @@ public class ExploreProcess extends BaritoneProcessHelper {
@Override
public String displayName0() {
return "Exploring around " + explorationOrigin + ", currently going to " + new GoalComposite(closestUncachedChunks(explorationOrigin));
return "Exploring around " + explorationOrigin + ", distance completed " + distanceCompleted + ", currently going to " + new GoalComposite(closestUncachedChunks(explorationOrigin, calcFilter()));
}
}

View File

@@ -0,0 +1,288 @@
/*
* 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.Item;
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 final class FarmProcess extends BaritoneProcessHelper implements IFarmProcess {
private boolean active;
private List<BlockPos> locations;
private int tickCount;
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_SLICE,
Items.WHEAT_SEEDS,
Items.WHEAT,
Items.PUMPKIN_SEEDS,
Items.POTATO,
Items.CARROT,
Items.BEETROOT,
Blocks.PUMPKIN.asItem(),
Blocks.MELON.asItem(),
Items.NETHER_WART,
Blocks.SUGAR_CANE.asItem(),
Blocks.CACTUS.asItem()
);
public FarmProcess(Baritone baritone) {
super(baritone);
}
@Override
public boolean isActive() {
return active;
}
@Override
public void farm() {
active = true;
locations = null;
}
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, state -> true),
NETHERWART(Blocks.NETHER_WART, state -> state.get(BlockNetherWart.AGE) >= 3),
SUGARCANE(Blocks.SUGAR_CANE, 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().equals(Items.BONE_MEAL);
}
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);
}
if (Baritone.settings().mineGoalUpdateInterval.value != 0 && tickCount++ % Baritone.settings().mineGoalUpdateInterval.value == 0) {
Baritone.getExecutor().execute(() -> locations = WorldScanner.INSTANCE.scanChunkRadius(ctx, scan, 256, 10, 10));
}
if (locations == null) {
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
}
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";
}
}

View File

@@ -72,7 +72,7 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
if (entity == null) {
return false;
}
if (entity.isDead) {
if (!entity.isAlive()) {
return false;
}
if (entity.equals(ctx.player())) {
@@ -82,7 +82,12 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
}
private void scanWorld() {
cache = Stream.of(ctx.world().loadedEntityList, ctx.world().playerEntities).flatMap(List::stream).filter(this::followable).filter(this.filter).distinct().collect(Collectors.toCollection(ArrayList::new));
cache = Stream.of(ctx.world().loadedEntityList, ctx.world().playerEntities)
.flatMap(List::stream)
.filter(this::followable)
.filter(this.filter)
.distinct()
.collect(Collectors.toCollection(ArrayList::new));
}
@Override

View File

@@ -34,7 +34,7 @@ import net.minecraft.util.math.BlockPos;
import java.util.*;
public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBlockProcess {
public final class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBlockProcess {
private Block gettingTo;
private List<BlockPos> knownLocations;
@@ -42,6 +42,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
private BlockPos start;
private int tickCount = 0;
private int arrivalTickCount = 0;
public GetToBlockProcess(Baritone baritone) {
super(baritone);
@@ -53,6 +54,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
gettingTo = block;
start = ctx.playerFeet();
blacklist = new ArrayList<>();
arrivalTickCount = 0;
rescan(new ArrayList<>(), new CalculationContext(baritone));
}
@@ -117,7 +119,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
}
// blacklist the closest block and its adjacent blocks
public synchronized void blacklistClosest() {
public synchronized boolean blacklistClosest() {
List<BlockPos> newBlacklist = new ArrayList<>();
knownLocations.stream().min(Comparator.comparingDouble(ctx.player()::getDistanceSq)).ifPresent(newBlacklist::add);
outer:
@@ -140,6 +142,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
}
logDebug("Blacklisting unreachable locations " + newBlacklist);
blacklist.addAll(newBlacklist);
return !newBlacklist.isEmpty();
}
// safer than direct double comparison from distanceSq
@@ -195,6 +198,10 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
return true;
}
}
if (arrivalTickCount++ > 20) {
logDirect("Right click timed out");
return true;
}
return false; // trying to right click, will do it next tick or so
}
}
@@ -206,7 +213,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
if (!Baritone.settings().enterPortal.value) {
return false;
}
return block == Blocks.PORTAL;
return block == Blocks.NETHER_PORTAL;
}
private boolean rightClickOnArrival(Block block) {

View File

@@ -22,16 +22,21 @@ import baritone.api.pathing.goals.*;
import baritone.api.process.IMineProcess;
import baritone.api.process.PathingCommand;
import baritone.api.process.PathingCommandType;
import baritone.api.utils.BlockUtils;
import baritone.api.utils.IPlayerContext;
import baritone.api.utils.Rotation;
import baritone.api.utils.RotationUtils;
import baritone.api.utils.input.Input;
import baritone.cache.CachedChunk;
import baritone.cache.ChunkPacker;
import baritone.cache.WorldScanner;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.MovementHelper;
import baritone.utils.BaritoneProcessHelper;
import baritone.utils.BlockStateInterface;
import net.minecraft.block.Block;
import net.minecraft.block.BlockAir;
import net.minecraft.block.BlockFalling;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.init.Blocks;
@@ -43,6 +48,8 @@ import net.minecraft.world.World;
import java.util.*;
import java.util.stream.Collectors;
import static baritone.api.pathing.movement.ActionCosts.COST_INF;
/**
* Mine blocks of a certain type
*
@@ -72,35 +79,61 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
@Override
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
if (desiredQuantity > 0) {
Item item = mining.get(0).getItemDropped(mining.get(0).getDefaultState(), new Random(), 0);
Item item = mining.get(0).getItemDropped(mining.get(0).getDefaultState(), ctx.world(), null, 0).asItem();
int curr = ctx.player().inventory.mainInventory.stream().filter(stack -> item.equals(stack.getItem())).mapToInt(ItemStack::getCount).sum();
System.out.println("Currently have " + curr + " " + item);
if (curr >= desiredQuantity) {
logDirect("Have " + curr + " " + item.getItemStackDisplayName(new ItemStack(item, 1)));
logDirect("Have " + curr + " " + item.getDisplayName(new ItemStack(item, 1)));
cancel();
return null;
}
}
if (calcFailed && !knownOreLocations.isEmpty() && Baritone.settings().blacklistClosestOnFailure.value) {
logDirect("Unable to find any path to " + mining + ", blacklisting presumably unreachable closest instance...");
knownOreLocations.stream().sorted(Comparator.comparingDouble(ctx.player()::getDistanceSq)).findFirst().ifPresent(blacklist::add);
knownOreLocations.removeIf(blacklist::contains);
calcFailed = false; // 😎
}
if (calcFailed) {
logDirect("Unable to find any path to " + mining + ", canceling Mine");
if (!knownOreLocations.isEmpty() && Baritone.settings().blacklistClosestOnFailure.value) {
logDirect("Unable to find any path to " + mining + ", blacklisting presumably unreachable closest instance...");
knownOreLocations.stream().min(Comparator.comparingDouble(ctx.player()::getDistanceSq)).ifPresent(blacklist::add);
knownOreLocations.removeIf(blacklist::contains);
} else {
logDirect("Unable to find any path to " + mining + ", canceling Mine");
cancel();
return null;
}
}
if (!Baritone.settings().allowBreak.value) {
logDirect("Unable to mine when allowBreak is false!");
cancel();
return null;
}
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.value;
List<BlockPos> curr = new ArrayList<>(knownOreLocations);
if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain
List<BlockPos> curr = new ArrayList<>(knownOreLocations);
CalculationContext context = new CalculationContext(baritone, true);
Baritone.getExecutor().execute(() -> rescan(curr, context));
}
if (Baritone.settings().legitMine.value) {
addNearby();
}
Optional<BlockPos> shaft = curr.stream()
.filter(pos -> pos.getX() == ctx.playerFeet().getX() && pos.getZ() == ctx.playerFeet().getZ())
.filter(pos -> pos.getY() >= ctx.playerFeet().getY())
.filter(pos -> !(BlockStateInterface.get(ctx, pos).getBlock() instanceof BlockAir)) // after breaking a block, it takes mineGoalUpdateInterval ticks for it to actually update this list =(
.min(Comparator.comparingDouble(ctx.player()::getDistanceSq));
baritone.getInputOverrideHandler().clearAllKeys();
if (shaft.isPresent() && ctx.player().onGround) {
BlockPos pos = shaft.get();
IBlockState state = baritone.bsi.get0(pos);
if (!MovementHelper.avoidBreaking(baritone.bsi, pos.getX(), pos.getY(), pos.getZ(), state)) {
Optional<Rotation> rot = RotationUtils.reachable(ctx, pos);
if (rot.isPresent() && isSafeToCancel) {
baritone.getLookBehavior().updateTarget(rot.get(), true);
MovementHelper.switchToBestToolFor(ctx, ctx.world().getBlockState(pos));
if (ctx.isLookingAt(pos) || ctx.playerRotations().isReallyCloseTo(rot.get())) {
baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_LEFT, true);
}
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
}
}
}
PathingCommand command = updateGoal();
if (command == null) {
// none in range
@@ -127,7 +160,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
if (!locs.isEmpty()) {
List<BlockPos> locs2 = prune(new CalculationContext(baritone), new ArrayList<>(locs), mining, ORE_LOCATIONS_COUNT, blacklist);
// can't reassign locs, gotta make a new var locs2, because we use it in a lambda right here, and variables you use in a lambda must be effectively final
Goal goal = new GoalComposite(locs2.stream().map(loc -> coalesce(ctx, loc, locs2)).toArray(Goal[]::new));
Goal goal = new GoalComposite(locs2.stream().map(loc -> coalesce(loc, locs2)).toArray(Goal[]::new));
knownOreLocations = locs2;
return new PathingCommand(goal, legit ? PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH : PathingCommandType.REVALIDATE_GOAL_AND_PATH);
}
@@ -177,25 +210,88 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
knownOreLocations = locs;
}
private static Goal coalesce(IPlayerContext ctx, BlockPos loc, List<BlockPos> locs) {
private 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)
if (locs.contains(pos)) {
return true;
}
Block block = BlockStateInterface.getBlock(ctx, pos);
if (Baritone.settings().internalMiningAirException.value && block instanceof BlockAir) {
return true;
}
return mining.contains(block);
}
private Goal coalesce(BlockPos loc, List<BlockPos> locs) {
boolean assumeVerticalShaftMine = !(baritone.bsi.get0(loc.up()).getBlock() instanceof BlockFalling);
if (!Baritone.settings().forceInternalMining.value) {
return new GoalTwoBlocks(loc);
if (assumeVerticalShaftMine) {
// we can get directly below the block
return new GoalThreeBlocks(loc);
} else {
// we need to get feet or head into the block
return new GoalTwoBlocks(loc);
}
}
boolean upwardGoal = internalMiningGoal(loc.up(), ctx, locs);
boolean downwardGoal = internalMiningGoal(loc.down(), ctx, locs);
boolean doubleDownwardGoal = internalMiningGoal(loc.down(2), ctx, locs);
if (upwardGoal == downwardGoal) { // symmetric
if (doubleDownwardGoal && assumeVerticalShaftMine) {
// 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
// but only if assumeVerticalShaftMine
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 && assumeVerticalShaftMine) {
// this block and two below it are goals
// path into the center of the one below, because that includes directly below this one
return new GoalTwoBlocks(loc.down());
}
// upwardGoal false, downwardGoal true, doubleDownwardGoal false
// just this block and the one immediately below, no others
return new GoalBlock(loc.down());
}
private static class GoalThreeBlocks extends GoalTwoBlocks {
public GoalThreeBlocks(BlockPos pos) {
super(pos);
}
// Here, BlockStateInterface is used because the position may be in a cached chunk (the targeted block is one that is kept track of)
boolean upwardGoal = locs.contains(loc.up()) || (Baritone.settings().internalMiningAirException.value && BlockStateInterface.getBlock(ctx, loc.up()) == Blocks.AIR);
boolean downwardGoal = locs.contains(loc.down()) || (Baritone.settings().internalMiningAirException.value && BlockStateInterface.getBlock(ctx, loc.down()) == Blocks.AIR);
return upwardGoal == downwardGoal ? new GoalTwoBlocks(loc) : upwardGoal ? new GoalBlock(loc) : new GoalBlock(loc.down());
@Override
public boolean isInGoal(int x, int y, int z) {
return x == this.x && (y == this.y || y == this.y - 1 || y == this.y - 2) && z == this.z;
}
@Override
public double heuristic(int x, int y, int z) {
int xDiff = x - this.x;
int yDiff = y - this.y;
int zDiff = z - this.z;
return GoalBlock.calculate(xDiff, yDiff < -1 ? yDiff + 2 : yDiff == -1 ? 0 : yDiff, zDiff);
}
}
public static List<BlockPos> droppedItemsScan(List<Block> mining, World world) {
if (!Baritone.settings().mineScanDroppedItems.value) {
return new ArrayList<>();
return Collections.emptyList();
}
Set<Item> searchingFor = new HashSet<>();
for (Block block : mining) {
Item drop = block.getItemDropped(block.getDefaultState(), new Random(), 0);
Item ore = Item.getItemFromBlock(block);
Item drop = block.getItemDropped(block.getDefaultState(), world, null, 0).asItem();
Item ore = block.asItem();
searchingFor.add(drop);
searchingFor.add(ore);
}
@@ -214,24 +310,20 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
public static List<BlockPos> searchWorld(CalculationContext ctx, List<Block> mining, int max, List<BlockPos> alreadyKnown, List<BlockPos> blacklist) {
List<BlockPos> locs = new ArrayList<>();
List<Block> uninteresting = new ArrayList<>();
//long b = System.currentTimeMillis();
for (Block m : mining) {
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(m)) {
// maxRegionDistanceSq 2 means adjacent directly or adjacent diagonally; nothing further than that
locs.addAll(ctx.worldData.getCachedWorld().getLocationsOf(ChunkPacker.blockToString(m), Baritone.settings().maxCachedWorldScanCount.value, ctx.getBaritone().getPlayerContext().playerFeet().getX(), ctx.getBaritone().getPlayerContext().playerFeet().getZ(), 2));
locs.addAll(ctx.worldData.getCachedWorld().getLocationsOf(BlockUtils.blockToString(m), Baritone.settings().maxCachedWorldScanCount.value, ctx.getBaritone().getPlayerContext().playerFeet().getX(), ctx.getBaritone().getPlayerContext().playerFeet().getZ(), 2));
} else {
uninteresting.add(m);
}
}
locs = prune(ctx, locs, mining, max, blacklist);
//System.out.println("Scan of cached chunks took " + (System.currentTimeMillis() - b) + "ms");
if (locs.isEmpty()) {
if (locs.isEmpty() || (Baritone.settings().extendCacheOnThreshold.value && locs.size() < max)) {
uninteresting = mining;
}
if (!uninteresting.isEmpty()) {
//long before = System.currentTimeMillis();
locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(ctx.getBaritone().getPlayerContext(), uninteresting, max, 10, 32)); // maxSearchRadius is NOT sq
//System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms");
}
locs.addAll(alreadyKnown);
return prune(ctx, locs, mining, max, blacklist);
@@ -264,7 +356,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
List<BlockPos> dropped = droppedItemsScan(mining, ctx.world);
dropped.removeIf(drop -> {
for (BlockPos pos : locs2) {
if (pos.distanceSq(drop) <= 9 && mining.contains(ctx.getBlock(pos.getX(), pos.getY(), pos.getZ())) && MineProcess.plausibleToBreak(ctx.bsi, pos)) { // TODO maybe drop also has to be supported? no lava below?
if (pos.distanceSq(drop) <= 9 && mining.contains(ctx.getBlock(pos.getX(), pos.getY(), pos.getZ())) && MineProcess.plausibleToBreak(ctx, pos)) { // TODO maybe drop also has to be supported? no lava below?
return true;
}
}
@@ -278,11 +370,11 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
.filter(pos -> !ctx.bsi.worldContainsLoadedChunk(pos.getX(), pos.getZ()) || mining.contains(ctx.getBlock(pos.getX(), pos.getY(), pos.getZ())) || dropped.contains(pos))
// remove any that are implausible to mine (encased in bedrock, or touching lava)
.filter(pos -> MineProcess.plausibleToBreak(ctx.bsi, pos))
.filter(pos -> MineProcess.plausibleToBreak(ctx, pos))
.filter(pos -> !blacklist.contains(pos))
.sorted(Comparator.comparingDouble(ctx.getBaritone().getPlayerContext().playerFeet()::distanceSq))
.sorted(Comparator.comparingDouble(ctx.getBaritone().getPlayerContext().player()::getDistanceSq))
.collect(Collectors.toList());
if (locs.size() > max) {
@@ -291,23 +383,27 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
return locs;
}
public static boolean plausibleToBreak(BlockStateInterface bsi, BlockPos pos) {
if (MovementHelper.avoidBreaking(bsi, pos.getX(), pos.getY(), pos.getZ(), bsi.get0(pos))) {
public static boolean plausibleToBreak(CalculationContext ctx, BlockPos pos) {
if (MovementHelper.getMiningDurationTicks(ctx, pos.getX(), pos.getY(), pos.getZ(), ctx.bsi.get0(pos), true) >= COST_INF) {
return false;
}
// bedrock above and below makes it implausible, otherwise we're good
return !(bsi.get0(pos.up()).getBlock() == Blocks.BEDROCK && bsi.get0(pos.down()).getBlock() == Blocks.BEDROCK);
return !(ctx.bsi.get0(pos.up()).getBlock() == Blocks.BEDROCK && ctx.bsi.get0(pos.down()).getBlock() == Blocks.BEDROCK);
}
@Override
public void mineByName(int quantity, String... blocks) {
mine(quantity, blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(ChunkPacker::stringToBlockRequired).toArray(Block[]::new));
mine(quantity, blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(BlockUtils::stringToBlockRequired).toArray(Block[]::new));
}
@Override
public void mine(int quantity, Block... blocks) {
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.asList(blocks);
if (mining != null && !Baritone.settings().allowBreak.value) {
logDirect("Unable to mine when allowBreak is false!");
mining = null;
}
this.desiredQuantity = quantity;
this.knownOreLocations = new ArrayList<>();
this.blacklist = new ArrayList<>();

View File

@@ -22,15 +22,23 @@ import baritone.api.event.events.TickEvent;
import baritone.api.event.listener.AbstractGameEventListener;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalBlock;
import baritone.api.utils.Helper;
import baritone.api.utils.IPlayerContext;
import net.minecraft.client.GameSettings;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiMainMenu;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.client.tutorial.TutorialSteps;
import net.minecraft.server.integrated.IntegratedServer;
import net.minecraft.util.HttpUtil;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.GameType;
import net.minecraft.world.WorldSettings;
import net.minecraft.world.WorldType;
import net.minecraft.world.dimension.DimensionType;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
/**
* Responsible for automatically testing Baritone's pathing algorithm by automatically creating a world with a specific
@@ -88,11 +96,13 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
mc.launchIntegratedServer("BaritoneAutoTest", "BaritoneAutoTest", worldsettings);
}
IntegratedServer server = mc.getIntegratedServer();
// If the integrated server is launched and the world has initialized, set the spawn point
// to our defined starting position
if (mc.getIntegratedServer() != null && mc.getIntegratedServer().worlds[0] != null) {
mc.getIntegratedServer().worlds[0].setSpawnPoint(STARTING_POSITION);
mc.getIntegratedServer().worlds[0].getGameRules().setOrCreateGameRule("spawnRadius", "0");
if (server != null && server.getWorld(DimensionType.OVERWORLD) != null) {
server.getWorld(DimensionType.OVERWORLD).setSpawnPoint(STARTING_POSITION);
server.getWorld(DimensionType.OVERWORLD).getGameRules().setOrCreateGameRule("spawnRadius", "0", server);
}
if (event.getType() == TickEvent.Type.IN) { // If we're in-game
@@ -100,7 +110,7 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
// Force the integrated server to share the world to LAN so that
// the ingame pause menu gui doesn't actually pause our game
if (mc.isSingleplayer() && !mc.getIntegratedServer().getPublic()) {
mc.getIntegratedServer().shareToLAN(GameType.getByName("survival"), false);
mc.getIntegratedServer().shareToLAN(GameType.getByName("survival"), false, HttpUtil.getSuitableLanPort());
}
// For the first 200 ticks, wait for the world to generate
@@ -122,7 +132,16 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
// If we have reached our goal, print a message and safely close the game
if (GOAL.isInGoal(ctx.playerFeet())) {
System.out.println("Successfully pathed to " + ctx.playerFeet() + " in " + event.getCount() + " ticks");
try {
File file = new File("success");
System.out.println("Writing success to " + file.getAbsolutePath());
Files.write(file.getAbsoluteFile().toPath(), "Success!".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
mc.shutdown();
mc.shutdownMinecraftApplet();
System.exit(0);
}
// If we have exceeded the expected number of ticks to complete the pathing

Some files were not shown because too many files have changed in this diff Show More