Compare commits

...

362 Commits

Author SHA1 Message Date
Leijurv
6a175379fb v1.2.16 2023-01-13 11:10:24 -08:00
leijurv
85c21fa8e3 add comment 2023-01-12 14:52:38 -08:00
leijurv
bc8c823045 Merge pull request #3775 from ZacSharp/pr/frostwalker
Allow pathing to use frostwalker
2023-01-12 14:51:35 -08:00
ZacSharp
9935da8a6f Add explanation and add extra check 2023-01-12 22:18:54 +01:00
ZacSharp
c39b6c3fe7 Don't grab state if we don't need it 2023-01-12 21:39:55 +01:00
leijurv
c47a6f92c5 Merge pull request #3786 from Entropy5/master
bugfix for odd height schematics
2023-01-12 12:03:51 -08:00
leijurv
778628da30 Merge pull request #3789 from Argentoz/patch-1
Fix world border check
2023-01-12 12:03:00 -08:00
leijurv
ba0ca0cc65 Merge pull request #3788 from ZacSharp/pr/detectBrokenLoadHook
Make the world cache work even when mods break our world load hook
2023-01-12 11:39:41 -08:00
leijurv
fba3828479 Merge pull request #3735 from ZacSharp/pr/breakNextToLava
Allow breaking next to some liquids
2023-01-12 10:08:09 -08:00
Argentoz
c8dd4f26f7 Fix :)
WTF
2023-01-12 15:02:54 +03:00
Entropy5
16a62625b3 this seems to work as well? 2023-01-12 04:29:31 +01:00
ZacSharp
de5f6d5fce Apply suggested reordering 2023-01-11 23:56:52 +01:00
Entropy5
98a87d099b zac suggestion 2023-01-11 04:36:15 +01:00
ZacSharp
a6f3c95684 Don't spam the log when in a replay 2023-01-10 18:58:17 +01:00
ZacSharp
75e39e7ef5 Log when doing things out of the ordinary 2023-01-10 18:56:33 +01:00
ZacSharp
77b2b26a7a Add fix for 1.19.3 here already 2023-01-10 18:55:46 +01:00
ZacSharp
1680eeb80d Handle mods breaking our world loading hook 2023-01-10 17:25:32 +01:00
Entropy5
9a9b4a1874 bugfix for odd height schematics 2023-01-10 05:56:30 +01:00
leijurv
145a944860 Merge pull request #3785 from Entropy5/master
buildonlyselection optimization
2023-01-08 19:03:49 -10:00
leijurv
dd127ff3e7 Merge pull request #3782 from ZacSharp/pr/updateWorkflows
Update workflows
2023-01-08 18:32:07 -10:00
Entropy5
b0fb474e1d buildinlayers ~ buildonlyselection lag fix for big schematics (skips layers more properly) 2023-01-09 02:33:10 +01:00
ZacSharp
a1a94ec0d1 Fix step name 2023-01-06 04:26:03 +01:00
ZacSharp
678f8bc77f Use Temurin JDK 2023-01-06 04:25:03 +01:00
ZacSharp
41968546d1 Update workflows 2023-01-06 04:09:56 +01:00
ZacSharp
f76283ebfe Remove unused imports 2023-01-03 00:50:56 +01:00
ZacSharp
e59bf9ab97 Grab block only once 2022-12-30 16:09:45 +01:00
ZacSharp
b2f66241d5 Merge remote-tracking branch 'upstream/master' into pr/frostwalker 2022-12-30 15:57:17 +01:00
leijurv
cfdbc851a0 Merge pull request #3600 from Imeguras/master
Added the ability to use KmM as abreviatures
2022-12-24 00:14:04 -08:00
leijurv
6ccebdc978 Merge pull request #3703 from rycbar0/master
formula error
2022-12-24 00:12:47 -08:00
leijurv
df53040339 Merge pull request #3757 from Warpten/feature/paths-with-spaces-are-stupid
Improve handling spaces in paths during proguard pass
2022-12-24 00:08:04 -08:00
leijurv
42dc5b14b0 Merge pull request #3755 from wagyourtail/allowbreakanaywaymine
allowBreakAnyway should let mining happen
2022-12-24 00:07:00 -08:00
leijurv
e2538abcb1 Merge pull request #3743 from ZacSharp/patch-11
Fix Registry.unregister
2022-12-24 00:05:42 -08:00
leijurv
1697293f12 Merge pull request #3479 from scorbett123/caching_performance_upgrade
Caching performance upgrade
2022-12-23 23:57:14 -08:00
rycbar0
d60e1e8a05 Merge branch 'cabaletta:master' into master 2022-12-19 10:34:57 +01:00
Warpten
d157756d94 Improve handling spaces in paths during proguard pass 2022-12-12 01:08:49 +01:00
Wagyourtail
ea1914a248 missed a spot 2022-12-10 20:12:51 -07:00
Wagyourtail
85087ce04a smarter filter filtering 2022-12-10 19:25:57 -07:00
Wagyourtail
e09127eadf allowBreakAnyway should let mining happen 2022-12-10 16:35:51 -07:00
ZacSharp
e1095962a1 Fix Registry.unregister 2022-11-28 23:07:30 +01:00
ZacSharp
eabd1150b0 Allow breaking next to some liquids 2022-11-22 15:15:33 +01:00
Leijurv
93501248cd Merge pull request #3698 from ZacSharp/patch-10
Reliably clear keys when paused
2022-10-31 12:29:56 -07:00
Leijurv
3a945c8c10 Merge pull request #3697 from ZacSharp/pr/buildIgnoreProperties
 Add buildIgnoreProperties setting
2022-10-31 12:28:44 -07:00
rycbar0
3cef7a7911 formula error 2022-10-26 23:09:23 +02:00
ZacSharp
1cd2fb5b18 Reliably clear keys when paused 2022-10-24 22:49:12 +02:00
ZacSharp
ba3ca47f8c Add buildIgnoreProperties setting 2022-10-23 01:42:31 +02:00
scorbett123
4699b46744 Merge branch 'master' into caching_performance_upgrade 2022-10-03 21:25:23 +01:00
Leijurv
69ffdb7665 Merge pull request #3672 from rycbar0/master
Litematica Support for bariton
2022-10-03 12:52:18 -07:00
rycbar0
f9c5386e7a final changes 2022-10-03 21:39:53 +02:00
Leijurv
55273b5340 Merge pull request #3579 from lucasarden/master
Stop backfill from filling while paused
2022-10-03 12:23:02 -07:00
rycbar0
5cd1c9d15d Merge pull request #1 from rycbar0/LitematicaCommand
Adding a Litematica command to build loaded schematics.
2022-10-03 20:39:24 +02:00
rycbar0
b461b2af2f made a oopsie 2022-10-03 20:32:56 +02:00
rycbar0
3a5608566e auto formatting 2022-10-03 20:13:11 +02:00
rycbar0
fc65f22feb clean up and adding javadoc 2022-10-03 19:59:07 +02:00
rycbar0
f53bfa89a9 a fucking x and z mixup 2022-10-03 17:44:15 +02:00
rycbar0
fdfeeb2ffa need stronger pesticides, bugs keep multiplying 2022-10-03 02:35:25 +02:00
rycbar0
3e75cc7408 block mirroring and rotation 2022-10-01 22:59:47 +02:00
rycbar0
d1930e03e1 getCorrectedOrigin returns the correct origin 2022-10-01 22:51:36 +02:00
rycbar0
144a534bb3 debugging mirroring and rotating as well as refactoring 2022-10-01 17:14:05 +02:00
rycbar0
de1256cc80 remove spaghetti 2022-10-01 05:27:02 +02:00
rycbar0
76404c8af6 it works but its spaghetti 2022-10-01 02:01:46 +02:00
ZacSharp
fb814e912d Don't try parkouring out of water 2022-09-30 23:59:49 +02:00
ZacSharp
43ee86b4fe Don't try backplacing against water under carpet/lilypad 2022-09-30 22:41:09 +02:00
ZacSharp
eb697b7a17 Fix costs when assumeWalkOnWater stops us from relying on frostWalker 2022-09-30 22:40:23 +02:00
ZacSharp
3da5bbd267 Don't pillar from carpet/lilypad on water 2022-09-30 22:38:21 +02:00
ZacSharp
c14be17e53 Move this to a helper method and add missing cases 2022-09-30 22:27:32 +02:00
ZacSharp
45c0b38156 Fix jumping from packplaced blocks on water
Not having frostwalker means that we must have replaced the water with a throwaway, not that we are standing on water
2022-09-30 18:04:34 +02:00
rycbar0
025f6235f9 litematica command works and added schematic selection if more than 1 schematic is loaded
bug: if schematic origin isnt minimum corner schematic is built in the wrong place
2022-09-30 17:53:31 +02:00
rycbar0
4ba3c883e6 something is fishy with the getAllSchematicPlacements() methode but i want my progress saved 2022-09-30 13:32:31 +02:00
rycbar0
3a4168a661 Merge branch 'master' into LitematicaCommand 2022-09-30 00:42:17 +02:00
rycbar0
484b3326c7 auto-format all files I touched 2022-09-29 21:52:15 +02:00
rycbar0
e99fcbbe36 Change requests part two 2022-09-29 21:47:42 +02:00
rycbar0
7ba3de57d0 credits LitematicaBitArray 2022-09-29 20:20:38 +02:00
rycbar0
5ff274f040 Change requests part one 2022-09-29 19:58:05 +02:00
schmar03
293f5db172 LitematicaCommand added to build loaded schematics 2022-09-28 14:15:48 +02:00
schmar03
d928e705b9 LitematicaCommand added to build loaded schematics 2022-09-28 12:09:38 +02:00
rycbar0
7a48824ced codacy issue #2,#3 and #4 fix 2022-09-26 22:32:25 +02:00
rycbar0
8aa8918124 codacy issue #1 and #5 fix 2022-09-26 22:23:38 +02:00
rycbar0
a091c17b83 Added mixin to properly handle Long Arrays 2022-09-26 21:04:09 +02:00
rycbar0
52aa0d9b8a more cleanup 2022-09-26 20:04:57 +02:00
rycbar0
3d8eddc4e1 cleanup 2022-09-26 19:23:09 +02:00
rycbar0
295265c261 refactoring 2022-09-26 17:43:54 +02:00
rycbar0
376d6422ec refactoring 2022-09-26 16:18:43 +02:00
rycbar0
113e340474 version check added 2022-09-26 16:09:41 +02:00
rycbar0
c89d8b69e5 ref files removed 2022-09-26 16:08:37 +02:00
rycbar0
70303634f5 ref files added 2022-09-26 15:59:55 +02:00
rycbar0
325aa7201b bug fix 2022-09-26 02:51:06 +02:00
rycbar0
75a3fc699e Code clean up 2022-09-26 01:18:56 +02:00
rycbar0
3cd8ce8323 Multiple Sub-region support 2022-09-26 00:58:32 +02:00
rycbar0
240e81a9e0 Refactoring 2022-09-25 18:22:59 +02:00
rycbar0
40449400d3 State of Emerson 2022-09-25 16:55:08 +02:00
ZacSharp
9ffe4f2c25 Fix parkour with frostwalker with/without throwaways
* Placing throwaways with allowPlace disabled
* Failing without throwaways
2022-09-01 13:14:33 +02:00
ZacSharp
af95f77134 Fix OOB and check for direction and include parkour 2022-09-01 13:14:24 +02:00
ZacSharp
78f1c45e13 Don't overshoot descends before using frostwalker 2022-08-31 23:39:09 +02:00
ZacSharp
cf47573298 Merge remote-tracking branch 'upstream/master' into pr/frostwalker 2022-08-30 00:18:07 +02:00
ZacSharp
96ba96ca69 Fix some more edge cases 2022-08-29 18:47:54 +02:00
ZacSharp
da998eb469 Complete frostwalker usage 2022-08-29 16:59:01 +02:00
ZacSharp
e75a4b95cc Mostly working usage of frostwalker
* Sometimes overshoots Descend-Traverse chains onto water
* Unwanted interactions with assumeWalkOnWater
2022-08-29 12:53:02 +02:00
Imeguras
344085f4ef Added the ability to use KmM as abreviatures
for example 1m is equals to 1 million  while 1K is 1000
2022-08-08 12:00:48 +01:00
Lucas Arden
d37a6a0b2d Added check for placed blocks in backfill 2022-07-26 14:21:32 -07:00
Lucas Arden
d7fc916d20 Added check for pathing 2022-07-24 21:37:45 -07:00
Leijurv
80a4757242 baritone complies faster if the files are less bytes 2022-07-15 01:36:01 -07:00
Leijurv
658048ff2d fix snow and tweak others 2022-07-14 22:11:13 -07:00
Leijurv
0587223da8 better constants 2022-07-14 22:02:19 -07:00
Leijurv
2d1b81dc20 vastly increase cuteness by removing the optional boolean 2022-07-14 22:00:18 -07:00
Leijurv
0bd16fb81a bit literals are meh 2022-07-14 21:56:25 -07:00
Leijurv
0c1fec5d1e crucial performance optimization 2022-07-14 21:54:32 -07:00
Leijurv
ee16eb7fde funnier this way 2022-07-14 21:47:18 -07:00
Leijurv
5c9aeab6b4 add cmt 2022-07-14 21:44:42 -07:00
Leijurv
5c7cae9ab0 fix literally wrong comment that did not match subsequent code 2022-07-14 21:43:14 -07:00
Leijurv
93fa6cf875 introduce MAYBE and fix more allocation cases 2022-07-14 21:42:38 -07:00
Leijurv
5b7bee977b also don't construct an optional for slabs 2022-07-14 21:38:38 -07:00
Leijurv
8018dac396 fix default case that instantiated an optional for non stairs 2022-07-14 21:38:02 -07:00
Leijurv
85ab317c6c simplify, remove setting changed event, always construct new precomputeddata 2022-07-14 21:35:30 -07:00
scorbett123
6b0fb1721b These should be all the suggested changes for the caching of can walk through block states 2022-07-14 17:18:02 +01:00
scorbett123
fdcdcbb85f Switch to using an int[] for storing precomputed data, and also use lazy loading 2022-07-14 12:49:47 +01:00
Leijurv
4e2095d251 almost forgot 2022-07-09 22:15:20 -07:00
Leijurv
51275b3a65 make #paws be an alias for #pause 2022-07-09 22:06:39 -07:00
scorbett123
8d480cefb9 Switch to throwable and readd check for glass / stained glass 2022-07-06 14:45:54 +01:00
scorbett123
3e7f9039c4 Don't construct new optionals in movement helper 2022-07-06 14:38:33 +01:00
Leijurv
49828baae3 Merge pull request #3296 from ZacSharp/findImprovements
Find improvements
2022-07-05 15:32:02 -07:00
Leijurv
a73e1185dc Merge pull request #3533 from Echocage/SprintFix
Fix for a sprint bug that can cause death
2022-07-05 15:27:10 -07:00
Echocage
441dceb731 Narrowed scope and we now only call canSprintFromDescendInto when our next & next_next movements are both MovementDescends 2022-06-29 17:54:28 -05:00
Echocage
57c4f9e103 Undid previous change, updated to instead check the next and the next_next block 2022-06-27 18:38:54 -05:00
Echocage
2741fc2683 Swapped the order of checks within canSprintFromDescendInto 2022-06-27 15:06:27 -05:00
scorbett123
868c023dbd Fix a couple of things I missed 2022-06-08 14:20:25 +01:00
scorbett123
e7c357ab7f Make precomputed data refresh every 200 ticks (10 seconds) 2022-06-08 14:14:14 +01:00
scorbett123
9e1a5008ed Move caching functions into MovementHelper 2022-06-07 21:52:24 +01:00
scorbett123
a6557121a0 fix github actions compiling. 2022-05-31 15:08:52 +01:00
scorbett123
2dad6262cf Remove some benchmarking and fix loading of settings. 2022-05-31 14:56:23 +01:00
scorbett123
af1eb58bb8 Implement Leijurv's precomputed data idea 2022-05-31 14:43:58 +01:00
Leijurv
17a2aa42e9 Merge pull request #3463 from ZacSharp/patch-8
Deal with others replacing the chat gui
2022-05-23 13:47:22 -07:00
Leijurv
231f671400 Merge pull request #3433 from ZacSharp/patch-7
Fix "missing null"
2022-05-23 13:46:27 -07:00
ZacSharp
221eba11dd Deal with others replacing the chat gui 2022-05-20 01:31:09 +02:00
ZacSharp
ad40a9225e Fix leaking incorrect positions
It was only cleared when the previous one was canceled, not when it was directly replaced by the next one.
2022-05-03 23:25:01 +02:00
Leijurv
cbef05838d Merge pull request #3388 from scorbett123/make_eta_show_ticks
Improve output to user in eta command
2022-04-19 16:33:37 -07:00
scorbett123
2cf973809a eta command should default to NaN not just not showing the eta as suggested by ZacSharp 2022-04-12 12:15:42 +01:00
scorbett123
65974e15ba Improve output to user in eta command 2022-04-11 18:36:48 +01:00
Leijurv
dc6b32a154 Merge pull request #3356 from wagyourtail/forceAllowBreak
add `allowBreakAnyway` setting
2022-03-31 14:08:13 -07:00
Leijurv
76f593e4bb Merge pull request #3342 from PhlegethonAcheron/master
Added usage syntax to the documentation for buildValidSubstitutes and buildSubstitutes
2022-03-31 14:07:42 -07:00
Leijurv
15b991a48e Merge pull request #3309 from wagyourtail/patch-2
fix inner class attribute being stripped
2022-03-31 14:01:45 -07:00
Leijurv
702d0790bc Merge pull request #3327 from scorbett123/fix-chunk-saving-crash
If context.player() returns none we don't want to use its position for pruning.
2022-03-31 13:58:11 -07:00
Wagyourtail
2953e2c522 make codacy happy 2022-03-24 18:16:19 -07:00
Wagyourtail
bf450b7d68 rename to allowBreakAnyway 2022-03-24 17:34:31 -07:00
Wagyourtail
4e6b6d97ce add forceAllowBreak setting 2022-03-24 17:33:33 -07:00
PhlegethonAcheron
6aadd00e72 Added usage syntax to the documentation for buildValidSubstitutes and buildSubstitutes 2022-03-20 15:41:25 -04:00
scorbett123
e036f5360c If context.player() returns none we don't want to use its position for pruning. 2022-03-16 20:12:56 +00:00
Leijurv
8c2aae2ddc Merge pull request #3324 from wagyourtail/master
reimplement death and bed waypoints
2022-03-15 19:06:50 -07:00
Wagyourtail
511941c714 reimplement death and bed waypoints 2022-03-15 18:39:19 -07:00
wagyourtail
e58220e2c4 fix inner class attribute being stripped 2022-03-08 19:45:05 -07:00
Leijurv
02711a73ed fix codacy 2022-03-08 15:14:00 -08:00
Leijurv
25d418e96b 1.15 is deprecated 2022-03-08 15:04:34 -08:00
Leijurv
10430f8142 bump to 1.18.2 2022-03-08 15:01:48 -08:00
Leijurv
8aba97b577 update for 1.8.3 2022-03-08 15:00:14 -08:00
Leijurv
8fe5b2369a Merge pull request #3301 from wagyourtail/toolmaterial-fix
fix modded toolmaterials (1.12.2)
2022-03-08 14:45:45 -08:00
Wagyourtail
dc6c87b58d fix modded toolmaterials 2022-03-07 15:53:13 -07:00
ZacSharp
ef4e19002b Provide more information for #find
Always log something to chat so people don't think it's broken and make sure they know about the restriction to cached blocks.
2022-03-05 22:27:27 +01:00
ZacSharp
e6ee5fc6b8 Make positions from #find clickable 2022-03-05 21:42:27 +01:00
Leijurv
b19c935da1 Merge pull request #3256 from ehylo/master
Update Setup and Usage guides
2022-02-09 16:35:54 -08:00
ehylo
0ade37f14f Update Setup and Usage guides
Also fix 2 settings that just don't have a description for some reason, and add some information to the find command because that also for some reason did not have anything there. The descriptions I put may not be detailed enough so please let me know if things should change
2022-02-08 21:13:51 -08:00
Leijurv
91be4c4643 Merge pull request #3093 from ZacSharp/fixBlockOptionalMetaObfuscation
Fix chat error messages being obfuscated for block type arguments
2022-02-08 10:52:25 -08:00
Leijurv
d2b62e2d21 Merge pull request #3239 from scorbett123/world_border_checks
Add some world border checks
2022-02-08 10:49:00 -08:00
Leijurv
7052fe6225 put this on its own line 2022-02-07 22:03:31 -08:00
scorbett123
49357790f1 fix world border checks
Signed-off-by: scorbett123 <50634068+scorbett123@users.noreply.github.com>
2022-02-03 08:06:01 +00:00
Leijurv
694219e497 Merge pull request #3243 from wagyourtail/master
fix getting stuck on cauldrons (fixes #3099)
2022-02-02 21:10:47 -08:00
Wagyourtail
9b70ace180 fix getting stuck on cauldrons (fixes #3099) 2022-02-02 22:04:15 -07:00
Leijurv
e0a53144db bump most recent jars 2022-02-02 16:10:14 -08:00
Leijurv
25de332492 mfw this also needs to be in master 2022-02-02 15:53:43 -08:00
Leijurv
2d0f10c79f link to branches 2022-02-02 15:53:24 -08:00
scorbett123
74ea803651 Add world border checks to MovementHelper 2022-02-02 20:36:36 +00:00
Leijurv
0908e509a1 simplify a bit more 2022-02-02 00:51:24 -08:00
Leijurv
ad14226c5c lets not keep updating this 2022-02-02 00:50:48 -08:00
Leijurv
3fcc032547 readme updates for new release 2022-02-02 00:50:12 -08:00
Leijurv
b52de9b197 Merge pull request #2621 from wagyourtail/replaymodfix-master
fix replaymod crash (on newer versions)
2022-02-02 00:15:50 -08:00
Leijurv
c2de6e3f3d Merge pull request #3173 from scorbett123/patch-4
Add unpause as an alias for resume
2022-02-01 23:57:21 -08:00
Leijurv
a5638bdba1 Merge pull request #3137 from scorbett123/remove_container_memory
Remove container memory
2022-02-01 23:56:49 -08:00
scorbett123
bb8e4bd737 Add unpause as an alias for resume
Some people can't seem to find out what to do to unpause baritone, so this should hopefully help them figure it out, as for some reason unpause makes more sense to people than resume.
2022-01-02 12:45:03 +00:00
Leijurv
7a96772a9b Merge pull request #3159 from Entropy5/master
Better buildignoredirection
2021-12-23 11:21:44 -10:00
Entropy5
9b07aa17e4 Merge remote-tracking branch 'origin/master' 2021-12-23 22:00:17 +01:00
Entropy5
90c59d5b8e undo 2021-12-23 21:59:20 +01:00
Entropy
fd3d5b66e9 Merge branch 'cabaletta:master' into master 2021-12-23 14:09:03 +01:00
Entropy5
d97346be6c check union of keys 2021-12-23 13:39:13 +01:00
Entropy5
9d13bcfe11 formatting 2021-12-22 00:20:21 +01:00
Leijurv
724ee62246 Merge pull request #3151 from ZacSharp/patch-4
Make rightClickContainerOnArrival click lit furnaces
2021-12-21 11:03:35 -10:00
Entropy5
26e8f02e85 merge 2021-12-21 20:30:28 +01:00
Entropy5
b3ff3d2466 universal buildignoredirection 2021-12-21 20:09:22 +01:00
Entropy5
9c3882e91f to lazy to spell 2021-12-21 12:49:44 +01:00
Entropy5
32a7657c4f Zac suggested this option to work universally, regardless of block type 2021-12-21 12:42:39 +01:00
Leijurv
54617bf634 reorder for performance 2021-12-21 01:32:47 -10:00
Leijurv
61a00b3965 Merge pull request #3148 from Entropy5/master
Option to ignore direction of certain blocks during building
2021-12-21 01:31:41 -10:00
Entropy
0214ffd158 Merge branch 'cabaletta:master' into master 2021-12-21 12:15:43 +01:00
Leijurv
1919f7b2a7 fix build again 2021-12-20 22:31:06 -10:00
ZacSharp
c2f4e00314 Make rightClickContainerOnArrival click lit furnaces 2021-12-18 00:31:21 +01:00
Entropy5
3adfa16db8 Option to ignore direction of certain blocks during building (because otherwise baritone just keeps breaking and replacing the same block) 2021-12-17 06:24:34 +01:00
scorbett123
90fcffdf2a Remove container memory
Signed-off-by: scorbett123 <50634068+scorbett123@users.noreply.github.com>
2021-12-12 19:50:27 +00:00
Leijurv
0ca84a790b Merge pull request #3119 from wagyourtail/patch-1
LEIJURV STOP BEING LAZY
2021-12-05 21:55:35 -08:00
wagyourtail
04802fbb15 LEIJURV STOP BEING LAZY 2021-12-05 22:54:37 -07:00
ZacSharp
21534d1c0b Fix chat error messages being obfuscated for block type arguments 2021-11-18 00:21:12 +01:00
Leijurv
8579332cdf Merge pull request #3033 from wagyourtail/neverbreak
AvoidBreak means never.
2021-10-27 12:53:45 -07:00
Wagyourtail
9dc9edbbee fix tabbing 2021-10-27 13:53:13 -06:00
Wagyourtail
2980bb0320 match leij's backwards compat suggestion 2021-10-27 13:45:30 -06:00
wagyourtail
084798bd1b Update src/api/java/baritone/api/Settings.java 2021-10-26 13:41:24 -06:00
wagyourtail
1c27b9b712 Update src/api/java/baritone/api/Settings.java 2021-10-26 13:34:10 -06:00
Leijurv
129ec8472c Merge pull request #3042 from ZacSharp/waypointImprovements
Waypoint improvements
2021-10-25 15:03:33 -07:00
ZacSharp
724162f37f Store deleted waypoints per world
Different dimensions are actually different worlds and the user might expect the wapoints to be restorable until they leave the server, so discrading them when the world changes would be too early.
2021-10-19 01:17:23 +02:00
ZacSharp
3244b102ad Add a way to restore deleted waypoints
Makes using the clickable text less dangerous when there are others writing in chat.
2021-10-18 02:42:58 +02:00
ZacSharp
c8966d22ba Don't create a new waypoint every time a bed is clicked.
Just the first time and always for the head part.
2021-10-17 23:44:21 +02:00
ZacSharp
6669d49636 Add a way to get the creation command for a waypoint 2021-10-17 15:10:14 +02:00
ZacSharp
3b480dabdb Make the tag argument optional, defaulting to USER
Listing all possible combinations in the usage as done before would have beed 8 lines just for the save command so I made it one special case, one combined line and a line explaining the defaults in the general waypoint help.

Also tab completion does not work when omitting either tag or name, because it starting to tab complete a position right from the first argument would probably only cause confusion and would be harder to implement because of the variable start position (names can even be numbers so it's impossible to do it 100% correctly)
2021-10-17 14:47:03 +02:00
ZacSharp
3e69281d61 Update usage of #waypoint
It now properly reports when either a tag or name can be specified and includes the clear subcommand
2021-10-17 14:06:07 +02:00
ZacSharp
1b04386b01 Allow saving unnamed waypoints by position 2021-10-17 13:53:55 +02:00
wagyourtail
1ca736692d more closely match the existing docs and add discourageBreaking 2021-10-15 17:58:13 -06:00
wagyourtail
4dc4795cb7 AvoidBreak means never. 2021-10-15 00:00:48 -06:00
Leijurv
bcc33362b8 Merge pull request #3024 from wagyourtail/followerror
better follow command error handling
2021-10-10 14:07:27 -07:00
wagyourtail
ba0b5f929f cleanup 2021-10-08 15:49:22 -06:00
wagyourtail
89c960c455 better follow command error handling 2021-10-08 14:58:17 -06:00
Leijurv
14178fcd14 rewrite comment since we haven't used pos.getY() in literally YEARS 2021-08-25 22:20:13 -07:00
Leijurv
5e0fe6d897 fix the comment explaining the sign flip
bug originates from august 17 2018 in f3d9ada675 (diff-b9b328a67abb41c2f842f367f83d95a2793c95cba83ab2e4542b31ed4c157819R101-R103)

absolutely wild how long this took to notice, see PR #2954
2021-08-25 22:18:23 -07:00
Leijurv
53ef26dabd Merge pull request #2954 from StylexTV/master
Fixed vertical cost calculation
2021-08-25 22:14:14 -07:00
StylexTV
3db5f2a67f Update GoalBlock.java 2021-08-22 10:28:42 +02:00
Leijurv
13d0e2a5bf Merge pull request #2879 from scorbett123/fixProguard
Fix proguard from being broken.
2021-07-18 23:29:56 -07:00
scorbett123
c3085ae34f Fix proguard
Signed-off-by: scorbett123 <50634068+scorbett123@users.noreply.github.com>
2021-07-18 18:37:20 +01:00
Leijurv
ce2ec8047e Merge pull request #2825 from Zephreo/parkour-place
ParkourPlace for shorter parkour jumps
2021-07-16 20:50:23 -07:00
Harry
335cb7016e fix verifiedMaxJump
- remove redundant assignment by changing some values
- testing Co-Authors

Co-Authored-By: Leijurv <leijurv@gmail.com>
2021-07-17 13:28:12 +10:00
Harry
7a7b050615 weird verifiedMaxJump 2021-07-17 12:34:58 +10:00
Leijurv
6ff7ae800a Merge pull request #2833 from ZacSharp/layerHeight
 Add layerHeight setting
2021-07-16 18:47:15 -07:00
Harry
2159773723 requested changes
- tabs changed to 4 spaces
- fixed checking if block place is behind player
2021-07-01 10:09:06 +10:00
ZacSharp
ab3a015d61 Add layerHeight setting 2021-06-24 23:33:48 +02:00
Harry
3142387e45 Fix collision early return
not tested yet
- fixes early returns
2021-06-23 06:25:10 +10:00
Harry
051325e10f allow smaller parkour place jumps
allows 2 and 1 block parkour place jumps
2021-06-21 10:58:11 +10:00
Harry
199d5d57d5 Update .gitignore 2021-06-21 09:49:18 +10:00
Leijurv
b96795c517 Merge pull request #2803 from scorbett123/farmInventory
Make farm use inventory when allowInventory is enabled.
2021-06-14 12:32:53 -10:00
scorbett123
64ba96daf2 Do edit suggested by leijurv 2021-06-14 20:44:32 +01:00
Leijurv
14b17d86e5 Merge pull request #2801 from scorbett123/master
Add github actions.
2021-06-13 10:21:51 -10:00
Leijurv
90d5f27026 Merge pull request #2804 from ZacSharp/selCopyPaste
 Add a clipboard to #sel
2021-06-13 10:21:10 -10:00
Leijurv
16386b8ddc Merge pull request #2796 from mankool0/itemSaverThreshold
Added itemSaverThreshold setting
2021-06-13 10:17:28 -10:00
Leijurv
cbef21b9ad Merge pull request #2800 from scorbett123/patch-3
Remove broken hit count badge
2021-06-13 10:16:51 -10:00
ZacSharp
cec44e3668 Add a clipboard to #sel 2021-06-13 00:21:52 +02:00
scorbett123
f09f1e7f85 Make farm use inventory when allowInventory is enabled. 2021-06-12 18:18:56 +01:00
scorbett123
95910bc6cb Cleanup - travis.org is now deprecated and can no longer be used. 2021-06-12 14:13:39 +01:00
scorbett123
cc488ccff0 Make actions run tests as well. 2021-06-12 14:09:50 +01:00
scorbett123
37e129bfb9 Create run_tests.yml 2021-06-12 14:08:04 +01:00
scorbett123
6adc923bcb Revert "update mapping.txt location"
This reverts commit 065470ce

Github doesn't seem to support ../
2021-06-12 14:07:35 +01:00
scorbett123
065470cecb update mapping.txt location 2021-06-12 14:02:31 +01:00
scorbett123
260989bda6 Update build java version for github actions. 2021-06-12 13:52:56 +01:00
scorbett123
64b6e0fd56 Remove broken hit count badge 2021-06-12 13:49:59 +01:00
scorbett123
8f45718b75 Try to create github actions
An attempt at github actions.
2021-06-12 11:27:27 +01:00
scorbett123
e66bb7a14b Make proguard output the mapping. 2021-06-12 11:14:59 +01:00
mankool
8bfe32eeef Added itemSaverThreshold 2021-06-09 10:34:45 -07:00
Leijurv
e85c1bbc0d Merge pull request #2736 from ZacSharp/exploreForBlocksForMining
Make MineProcess respect exploreForBlocks
2021-05-28 13:27:13 -07:00
ZacSharp
f99bf0d000 Make legitMode always explore 2021-05-28 22:18:33 +02:00
Leijurv
db24a2251f Merge pull request #2771 from ZacSharp/notificationCallback
More log callbacks
2021-05-26 11:32:53 -07:00
Leijurv
fcb3747690 Merge pull request #2776 from thecakeisalie25/master
Add "RenderGoalAsBox" Setting
2021-05-26 11:30:51 -07:00
Tabbs
dcc27a7447 oops forgot the javadoc 2021-05-25 14:52:16 -05:00
Tabbs
bea39bc613 Merge branch 'master' of https://github.com/thecakeisalie25/baritone 2021-05-25 14:44:59 -05:00
Tabbs
546493ba45 do our best to stop beacon animating
The game seems to animate the beacons anyway, so it does shake a little bit.
2021-05-25 14:44:54 -05:00
Tabbs
dda4928693 change name to renderGoalAnimated 2021-05-25 14:43:32 -05:00
Larson
7d144dd076 fix decimal
Co-authored-by: scorbett123 <50634068+scorbett123@users.noreply.github.com>
2021-05-25 14:33:13 -05:00
Tabbs
73e0700ea3 fix weird rendering issue 2021-05-25 12:41:36 -05:00
Tabbs
3fc36cf798 fix y to 1 if animation is disabled 2021-05-25 12:34:17 -05:00
ZacSharp
dbc43b445b Replace unhandled exception with a helpful message 2021-05-24 03:38:14 +02:00
ZacSharp
638fcd393a Don't try to tab complete hidden settings 2021-05-24 03:20:31 +02:00
ZacSharp
7b5f419713 Treat the new callbacks like the old one 2021-05-24 03:14:33 +02:00
ZacSharp
253fbad3db Make MineProcess respect exploreForBlocks 2021-05-10 22:37:35 +02:00
ZacSharp
522de3d4b7 Add callback settings for toast pop-ups and desktop notifications 2021-05-10 00:31:37 +02:00
ZacSharp
dc9ae67657 Move NotificationHelper to api and give Helper some methods for notifications 2021-05-10 00:26:33 +02:00
Leijurv
fccac8ed74 Merge pull request #2664 from ZacSharp/buildSelectedSchematic
Add setting to only build selected part of schematica schematic
2021-04-20 23:27:57 -07:00
Leijurv
24c895084e Merge pull request #2647 from scorbett123/patch-2
switch from forge mods to just other mods.
2021-04-20 23:15:37 -07:00
Leijurv
16fbfdecb5 Merge pull request #2645 from millennIumAMbiguity/patch-1
Added missing information to USAGE.md
2021-04-20 23:15:25 -07:00
Leijurv
b79e281074 Merge pull request #2635 from ZacSharp/autoTool
Invert disableAutoTool to autoTool
2021-04-20 23:15:10 -07:00
Leijurv
93ac380fd6 Merge pull request #2634 from ZacSharp/patch-2
fix typo
2021-04-20 23:13:57 -07:00
ZacSharp
46066d4cac Misc
* Rename schematicaOnlyBuildSelection to buildOnlySelection
* Make it useable with #build as well
* remove debugging code I forgot
2021-04-14 23:36:16 +02:00
ZacSharp
c13cf4f29c Add setting to only build selected part of schematica schematic 2021-04-13 23:09:54 +02:00
ZacSharp
a4f06a9e1e Update javadoc as well 2021-04-10 23:56:30 +02:00
scorbett123
cbc5fc8d08 switch from forge mods to just other mods. 2021-04-08 18:36:46 +01:00
millennIumAMbiguity
0a27c0b6e4 Added missing information to USAGE.md
Added missing information about the `farm` command.
2021-04-07 18:12:47 +02:00
ZacSharp
f348a20035 invert disableAutoTool to autoTool 2021-04-04 03:34:10 +02:00
ZacSharp
bdb98b487f fix typo 2021-04-04 03:17:35 +02:00
Leijurv
2cb6402189 Update README.md 2021-04-03 16:56:26 -07:00
Leijurv
861bb7a00a v1.2.15 2021-04-03 16:50:01 -07:00
Leijurv
43d5458a25 fix weird behavior where allowBreak false broke #goto 2021-04-03 16:41:45 -07:00
Leijurv
fe491e4a7d Merge pull request #1809 from Moondarker/master
Added "install" target for instant maven-ready releases
2021-04-03 13:40:56 -07:00
wagyourtail
9d1b979318 fix replaymod crash 2021-03-28 21:32:48 -07:00
Leijurv
c1794dd0ca reduce useless links 2021-03-25 10:41:16 -10:00
Leijurv
8f7d8b1cba Merge pull request #2611 from Flurrrr/master
Center badges and other stuff
2021-03-25 09:29:08 -10:00
flurr
8ebb8a04fa Center badges and other stuff
-center the badges
-re-arrange them to be more organized
-update the Aristois/Impact badges to the correct versions and fix broken link
2021-03-25 11:51:18 -07:00
Leijurv
ef6435a02a whatever i don't care 2021-03-23 22:44:20 -10:00
Leijurv
5cbe0a8230 Update README.md 2021-03-23 22:44:03 -10:00
Leijurv
dcef6b556c Update README.md 2021-03-23 22:42:39 -10:00
Leijurv
c07a636db2 Update README.md 2021-03-23 22:41:59 -10:00
Leijurv
a6be95fe33 Merge pull request #2606 from scorbett123/patch-1
fix typo
2021-03-23 10:19:11 -10:00
scorbett123
14149aa6b1 fix typo 2021-03-23 19:35:11 +00:00
Leijurv
ae901219fb Merge pull request #2526 from ZacSharp/buildSkipBlocks
Settings to alter block treatment while builing
2021-03-23 08:09:44 -10:00
Leijurv
6d9600d132 Update README.md 2021-03-21 13:59:00 -07:00
Leijurv
ccc55562cd Update README.md 2021-03-21 13:52:27 -07:00
ZacSharp
67d9ae881f don't allocate tons of empty lists 2021-03-09 12:31:02 +01:00
ZacSharp
61e0525ee8 Don't copy block state properties every time 2021-03-09 12:26:47 +01:00
ZacSharp
363519db02 treat all airs as air 2021-03-09 11:53:43 +01:00
Leijurv
4bc179bd2a Merge pull request #2462 from scorbett123/ModifiedImprovement
Improve #modified command to include original setting value.
2021-02-19 20:14:35 -08:00
Leijurv
76debda76e Merge pull request #1978 from ZacSharp/master
 Add improved ETA and a command to access it
2021-02-19 20:13:47 -08:00
Leijurv
b4eabe19cb Merge pull request #2482 from ZacSharp/schematicCacheClearing
Clear caches of schematics when moving them
2021-02-19 16:06:28 -08:00
ZacSharp
971b75860f Call reset() on static schematics as well 2021-02-19 23:57:33 +01:00
ZacSharp
5a926bf169 formatting 2021-02-19 23:52:18 +01:00
Leijurv
d34f37c563 Merge pull request #2476 from biscuut/patch-1
Fixed incorrect block pos world coordinates
2021-02-19 10:54:47 -08:00
Leijurv
6035a01019 Merge pull request #2481 from ZacSharp/buildRepeatCrash
Don't crash by buildRepeating too often
2021-02-19 10:49:06 -08:00
ZacSharp
c880f71dc8 Clear caches of schematics when moving them 2021-02-17 01:59:23 +01:00
ZacSharp
13422ef7ce lag > crash 2021-02-17 01:19:16 +01:00
Biscuit
84e2efd42c Fixed incorrect block pos world coordinates
Fix block pos being incorrect when converting chunk coordinates to world coordinates because of order of operations.
2021-02-15 14:21:03 -05:00
ZacSharp
113d26937d remove unused imports 2021-02-11 01:08:33 +01:00
ZacSharp
34606415d7 Don't mark skipped blocks as invalid just because they are far away 2021-02-10 23:45:12 +01:00
scorbett123
6b9c1f0a22 Improve #modified command to include original setting value.
Signed-off-by: scorbett123 <50634068+scorbett123@users.noreply.github.com>
2021-02-10 16:00:44 +00:00
ZacSharp
132cc0e131 make range initialization more readable 2021-02-10 10:25:17 +01:00
ZacSharp
5926369a56 formatting and comments 2021-02-10 10:15:14 +01:00
ZacSharp
ff068d374f Don't box doubles 2021-02-10 00:29:45 +01:00
Leijurv
4132d6ff61 Merge pull request #2138 from scorbett123/swordSaver
add useSwordToMine setting.
2021-02-08 16:54:37 -08:00
scorbett123
1f10199e64 Change use sword to mine to default to true.
Signed-off-by: scorbett123 <50634068+scorbett123@users.noreply.github.com>
2021-02-08 08:34:31 +00:00
Leijurv
e97704b37f Merge pull request #2139 from scorbett123/notifyOnDeath
notify users that their death position has been saved.
2021-02-07 14:32:43 -08:00
scorbett123
4ae81a3b0b Merge branch 'master' into swordSaver 2021-02-07 12:19:18 +00:00
Moondarker
f4ec9a8ec1 Merge pull request #2 from cabaletta/master
Fetching latest updates
2021-02-07 06:39:00 +03:00
Leijurv
711037b619 rearrange for consistency 2021-02-06 13:36:24 -08:00
Leijurv
b32c9f1724 Merge pull request #2107 from scorbett123/toolsSaver
add itemSaver setting.
2021-02-06 13:33:01 -08:00
Leijurv
be132c531e Update SETUP.md 2021-02-05 22:53:44 -08:00
Leijurv
fb8826caf4 Update README.md 2021-02-05 22:42:03 -08:00
Leijurv
adff60b118 Update README.md 2021-02-05 22:41:52 -08:00
Leijurv
8f863bf19b empty 2021-02-05 20:08:46 -08:00
ZacSharp
fd61207709 Fix heuristic(no args) returning wrong values 2021-01-28 01:40:33 +01:00
ZacSharp
8c1a9f460d Simple blockstate preservation for buildSubstitutes 2021-01-18 12:06:50 +01:00
ZacSharp
f6d4a315c7 Remove debug log 2021-01-18 11:58:42 +01:00
ZacSharp
fc1a2a6112 Add buildSubstitutes setting to builder 2021-01-17 02:45:40 +01:00
ZacSharp
13547781d2 add buildValidSubstitutes setting to builder 2021-01-17 00:53:50 +01:00
ZacSharp
d375d1abc9 Add setting parser for mappings 2021-01-17 00:16:34 +01:00
ZacSharp
5e4f31f39e proper place/break costs for skipped blocks 2021-01-16 02:05:59 +01:00
ZacSharp
dba186347c remove likely useless code breaking buildSkipBlocks 2021-01-13 22:45:59 +01:00
ZacSharp
7988274d61 add buildSkipBlocks setting 2021-01-12 23:59:11 +01:00
Sam Corbett
b9eeab06a1 change useSwordToMine to default to false.
Signed-off-by: Sam Corbett <sam@corbettchocolates.com>
2020-11-02 07:47:36 +00:00
scorbett123
c0f7d5ab44 fix error made while copying and pasting.
Signed-off-by: scorbett123 <sam@corbettchocolates.com>
2020-11-01 17:30:53 +00:00
scorbett123
60f81fb89d notify users that their death position has been saved.
Signed-off-by: scorbett123 <sam@corbettchocolates.com>
2020-11-01 17:18:31 +00:00
scorbett123
49bc96dc7e add useSwordToMine setting.
Signed-off-by: scorbett123 <sam@corbettchocolates.com>
2020-11-01 16:12:38 +00:00
Sam Corbett
9922382581 don't fall back onto the first slot if it has a low durability item in the slot.
Signed-off-by: Sam Corbett <sam@corbettchocolates.com>
2020-10-28 08:44:40 +00:00
scorbett123
4aa52d2f2e add itemSaver setting.
Signed-off-by: scorbett123 <sam@corbettchocolates.com>
2020-10-24 18:03:29 +01:00
ZacSharp
9393192036 Slight change to heuristic(no args) 2020-10-16 01:30:04 +02:00
ZacSharp
3cdbc4cb83 👌formatting in of comments 2020-10-15 21:48:17 +02:00
ZacSharp
0c7741120a 👌formatting 2020-10-15 00:05:54 +02:00
ZacSharp
e529438c7e Don't use Abs on Sqrt 2020-10-14 21:14:17 +02:00
ZacSharp
aebfbba20e Also override heuristic(no args) when overriding isInGoal() 2020-09-20 22:39:48 +02:00
ZacSharp
85cc86346c Actually use Y and Z bounds for Y and Z 2020-09-20 22:20:24 +02:00
ZacSharp
b20e095683 add heuristic(no args) to GoalNear and GoalRunAway
not really a good solution but better than nothing
2020-09-20 00:29:31 +02:00
ZacSharp
b4d7f05165 🐛 fix two NPEs in estimatedTickToGoal
apparently `ctx.playerFeet()` and `startPosition` can be `null` before pathing the first time
2020-09-19 21:46:07 +02:00
ZacSharp
46a12754e9 🐛Reset ETA and return 0 if we are already there
not doing this caused a continuously increasing ETA when standing inside a `GoalNear` from `FollowProcess`
2020-09-19 00:30:25 +02:00
ZacSharp
411b2a0acc 🔨move ETA reset to it's own function 2020-09-18 23:58:06 +02:00
ZacSharp
7255ccbdaa add heuristic(no args) to GoalComposite
GoalNear and GoalRunAway are still missing it
2020-09-06 16:42:05 +02:00
ZacSharp
45dc8b949d add a method to get the heuristic at the goal
this alows the ETA to work with goals not ending with a heuristic of 0

GoalComposite, GoalRunAway and GoalNear are still missing
2020-09-05 22:32:38 +02:00
ZacSharp
10e3a5afc4 negative ETAs are actually impossible now 2020-09-05 22:13:05 +02:00
ZacSharp
303aa79ffb Update ETA formula, assuming heuritic at goal is 0 2020-09-04 23:56:01 +02:00
ZacSharp
35f3be9296 get rid of negative ETAs the lazy way 2020-09-02 22:59:13 +02:00
ZacSharp
695954bdb0 no eta after 0 ticks or with division by 0 2020-08-28 23:37:23 +02:00
ZacSharp
d29b3ee893 Fix copy/paste mistake in ETACommand.getLongDesc() 2020-08-28 01:19:06 +02:00
ZacSharp
d9cecb35cb rename Eta to ETA 2020-08-28 00:56:18 +02:00
ZacSharp
71dd6c6333 👌formatting 2020-08-27 01:16:17 +02:00
ZacSharp
56f13d314a Add eta command 2020-08-26 23:53:02 +02:00
ZacSharp
b628d67961 Add ETA for full path 2020-08-26 23:52:44 +02:00
Moondarker
8fe05c9119 fixup! Allow multi-artifact building for Jitpack and local Maven repos 2020-06-20 23:16:20 +03:00
Moondarker
e8e6a9bc5c Allow multi-artifact building for Jitpack and local Maven repos 2020-06-20 23:11:16 +03:00
92 changed files with 2839 additions and 920 deletions

View File

@@ -11,7 +11,7 @@ Operating system:
Java version:
Minecraft version:
Baritone version:
Forge mods (if used):
Other mods (if used):
## Exception, error or logs
Please find your `latest.log` or `debug.log` in this folder and attach it to the issue

39
.github/workflows/gradle_build.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
# This workflow will build a Java project with Gradle
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
name: Java CI with Gradle
on:
push:
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 8
uses: actions/setup-java@v3
with:
java-version: '8'
distribution: 'temurin'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew build
- name: Archive Artifacts
uses: actions/upload-artifact@v3
with:
name: Artifacts
path: dist/
- name: Archive mapping.txt
uses: actions/upload-artifact@v3
with:
name: Mappings
path: build/tmp/proguard/mapping.txt

26
.github/workflows/run_tests.yml vendored Normal file
View File

@@ -0,0 +1,26 @@
name: Tests
on:
push:
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 8
uses: actions/setup-java@v3
with:
java-version: '8'
distribution: 'temurin'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Executing tests
run: ./gradlew test

9
.gitignore vendored
View File

@@ -18,6 +18,15 @@ classes/
*.iws
/logs/
# Eclipse Files
.classpath
.project
.settings/
baritone_Client.launch
# Copyright Files
!/.idea/copyright/Baritone.xml
!/.idea/copyright/profiles_settings.xml
.vscode/launch.json

View File

@@ -1,28 +0,0 @@
language: java
sudo: required
services:
- docker
install:
- travis_retry docker build -t cabaletta/baritone .
script:
- docker run --name baritone cabaletta/baritone ./gradlew javadoc
- docker cp baritone:/code/dist dist
- ls dist
- cat dist/checksums.txt
deploy:
provider: releases
api_key:
secure: YOuiXoJNpB4bW89TQoY2IGXg0tqOKls55YMXsSPU6Mx8WzRu8CjjO/A8KA9nGfNrKM+NucjiKr/h53O2Dp2uyy0i0SLvav/G0MaBMeB1NlPRwFopi6tVPNaoZsvr8NW4BIURhspckYLpOTYWnfmOkIv8q7AxrjUZWPKDlq0dte20UxEqUE6msHJ7U9XlKo/4fX40kvWMfwGI2hTyAtL0cRT1QPsd+uW3OQjAPcQj+jKaWld46V8pBK8g9Qde9mo8HC9NBv97zw1bBF1EFkynW569kElHvaS2Opl2QLGaf66guDbpnqDpGHMhQrDdxsZHJ4RksyITn+8A9UArmbkU35BxKqBeQqOWxod2+M0axdLh1pvX43Q1t9n7RiZBf7GvV8vkXL5Sjf8v6Y4LqkJGhvQkTUwpH+0knwrE761DMCtBC34AiWG70D4u7msmhurkflr9kmRHSj/3lyJ1Q2lkt8L+FOAlQBVs64vXTsfgc6Yge7N0O3UD5hCkrDNoz3BzhNBdCkbdxdKCGip71UZgUNkPy9o3ui8jATNj9ypx3+U8ovqP0XWlJqUZmyeXyNGW9NrLeCkRLTlLnZ/dv6OPONa1oAu4TwF1w5A+TGRFZcZjH/PnZKZDQ1OYQOR6drLKRYdr2unvuf5KUKUGqZ7aYtLGhP0rBvGWddRV7DSmX/s=
all_branches: true
file_glob: true
file:
- dist/*
skip_cleanup: true
on:
tags: true
repo: cabaletta/baritone

View File

@@ -1,49 +1,69 @@
# 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/)
<p align="center">
<a href="https://github.com/cabaletta/baritone/releases/"><img src="https://img.shields.io/github/downloads/cabaletta/baritone/total.svg" alt="GitHub All Releases"/></a>
</p>
[![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)
[![Minecraft](https://img.shields.io/badge/MC-1.12.2-brightgreen.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/)
[![Minecraft](https://img.shields.io/badge/MC-1.14.4-brightgreen.svg)](https://github.com/cabaletta/baritone/tree/1.14.4/)
[![Minecraft](https://img.shields.io/badge/MC-1.15.2-brightgreen.svg)](https://github.com/cabaletta/baritone/tree/1.15.2/)
[![Minecraft](https://img.shields.io/badge/MC-1.16.4-brightgreen.svg)](https://github.com/cabaletta/baritone/tree/1.16.4/)
[![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/)
[![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)
![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.14%20/%20v1.3.8%20/%20v1.4.6%20/%20v1.5.3-brightgreen.svg)](https://impactclient.net/)
[![KAMI Blue integration](https://img.shields.io/badge/KAMI%20Blue%20integration-v1.2.14--master-green)](https://github.com/kami-blue/client)
[![ForgeHax integration](https://img.shields.io/badge/ForgeHax%20%22integration%22-scuffed-yellow.svg)](https://github.com/fr1kin/ForgeHax/)
[![Aristois add-on integration](https://img.shields.io/badge/Aristois%20add--on%20integration-v1.3.4%20/%20v1.4.1-green.svg)](https://gitlab.com/emc-mods-indrit/baritone_api)
[![rootNET integration](https://img.shields.io/badge/rootNET%20integration-v1.2.14-green.svg)](https://rootnet.dev/)
[![Future integration](https://img.shields.io/badge/Future%20integration-v1.2.12%20%2F%20v1.3.6%20%2F%20v1.4.4-red)](https://futureclient.net/)
[![RusherHack integration](https://img.shields.io/badge/RusherHack%20integration-v1.2.14-green)](https://rusherhack.org/)
[![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/)
<p align="center">
<a href="https://github.com/cabaletta/baritone/tree/master"><img src="https://img.shields.io/badge/MC-1.12.2-brightgreen.svg" alt="Minecraft"/></a>
<a href="https://github.com/cabaletta/baritone/tree/1.13.2"><img src="https://img.shields.io/badge/MC-1.13.2-yellow.svg" alt="Minecraft"/></a>
<a href="https://github.com/cabaletta/baritone/tree/1.14.4"><img src="https://img.shields.io/badge/MC-1.14.4-yellow.svg" alt="Minecraft"/></a>
<a href="https://github.com/cabaletta/baritone/tree/1.15.2"><img src="https://img.shields.io/badge/MC-1.15.2-yellow.svg" alt="Minecraft"/></a>
<a href="https://github.com/cabaletta/baritone/tree/1.16.5"><img src="https://img.shields.io/badge/MC-1.16.5-brightgreen.svg" alt="Minecraft"/></a>
<a href="https://github.com/cabaletta/baritone/tree/1.17.1"><img src="https://img.shields.io/badge/MC-1.17.1-brightgreen.svg" alt="Minecraft"/></a>
<a href="https://github.com/cabaletta/baritone/tree/1.18.2"><img src="https://img.shields.io/badge/MC-1.18.2-brightgreen.svg" alt="Minecraft"/></a>
</p>
A Minecraft pathfinder bot.
<p align="center">
<a href="https://travis-ci.com/cabaletta/baritone/"><img src="https://travis-ci.com/cabaletta/baritone.svg?branch=master" alt="Build Status"/></a>
<a href="https://github.com/cabaletta/baritone/releases/"><img src="https://img.shields.io/github/release/cabaletta/baritone.svg" alt="Release"/></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/license-LGPL--3.0%20with%20anime%20exception-green.svg" alt="License"/></a>
<a href="https://www.codacy.com/gh/cabaletta/baritone/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=cabaletta/baritone&amp;utm_campaign=Badge_Grade"><img src="https://app.codacy.com/project/badge/Grade/cadab857dab049438b6e28b3cfc5570e" alt="Codacy Badge"/></a>
<a href="https://github.com/cabaletta/baritone/blob/master/CODE_OF_CONDUCT.md"><img src="https://img.shields.io/badge/%E2%9D%A4-code%20of%20conduct-blue.svg?style=flat" alt="Code of Conduct"/></a>
<a href="https://snyk.io/test/github/cabaletta/baritone?targetFile=build.gradle"><img src="https://snyk.io/test/github/cabaletta/baritone/badge.svg?targetFile=build.gradle" alt="Known Vulnerabilities"/></a>
<a href="https://github.com/cabaletta/baritone/issues/"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" alt="Contributions welcome"/></a>
<a href="https://github.com/cabaletta/baritone/issues/"><img src="https://img.shields.io/github/issues/cabaletta/baritone.svg" alt="Issues"/></a>
<a href="https://github.com/cabaletta/baritone/issues?q=is%3Aissue+is%3Aclosed"><img src="https://img.shields.io/github/issues-closed/cabaletta/baritone.svg" alt="GitHub issues-closed"/></a>
<a href="https://github.com/cabaletta/baritone/pulls/"><img src="https://img.shields.io/github/issues-pr/cabaletta/baritone.svg" alt="Pull Requests"/></a>
<a href="https://github.com/cabaletta/baritone/graphs/contributors/"><img src="https://img.shields.io/github/contributors/cabaletta/baritone.svg" alt="GitHub contributors"/></a>
<a href="https://github.com/cabaletta/baritone/commit/"><img src="https://img.shields.io/github/commits-since/cabaletta/baritone/v1.0.0.svg" alt="GitHub commits"/></a>
<img src="https://img.shields.io/github/languages/code-size/cabaletta/baritone.svg" alt="Code size"/>
<img src="https://img.shields.io/github/repo-size/cabaletta/baritone.svg" alt="GitHub repo size"/>
<img src="https://tokei.rs/b1/github/cabaletta/baritone?category=code" alt="Lines of Code"/>
</p>
Baritone is the pathfinding system used in [Impact](https://impactclient.net/) since 4.4. There's a [showcase video](https://youtu.be/CZkLXWo4Fg4) made by @Adovin#0730 on Baritone which I recommend. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a (very old!) video I made showing off what it can do. [Tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa)
<p align="center">
<a href="https://impactclient.net/"><img src="https://img.shields.io/badge/Impact%20integration-v1.2.14%20/%20v1.3.8%20/%20v1.4.6%20/%20v1.5.3%20/%20v1.6.3-brightgreen.svg" alt="Impact integration"/></a>
<a href="https://github.com/kami-blue/client"><img src="https://img.shields.io/badge/KAMI%20Blue%20integration-v1.2.14--master-green" alt="KAMI Blue integration"/></a>
<a href="https://github.com/fr1kin/ForgeHax/"><img src="https://img.shields.io/badge/ForgeHax%20%22integration%22-scuffed-yellow.svg" alt="ForgeHax integration"/></a>
<a href="https://aristois.net/"><img src="https://img.shields.io/badge/Aristois%20add--on%20integration-v1.6.3-green.svg" alt="Aristois add-on integration"/></a>
<a href="https://rootnet.dev/"><img src="https://img.shields.io/badge/rootNET%20integration-v1.2.14-green.svg" alt="rootNET integration"/></a>
<a href="https://futureclient.net/"><img src="https://img.shields.io/badge/Future%20integration-v1.2.12%20%2F%20v1.3.6%20%2F%20v1.4.4-red" alt="Future integration"/></a>
<a href="https://rusherhack.org/"><img src="https://img.shields.io/badge/RusherHack%20integration-v1.2.14-green" alt="RusherHack integration"/></a>
</p>
The easiest way to install Baritone is to install [Impact](https://impactclient.net/), which comes with Baritone. The second easiest way (for 1.12.2 only) is to install the v1.2.* `api-forge` jar from [releases](https://github.com/cabaletta/baritone/releases). **For 1.12.2 Forge, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.2.14/baritone-api-forge-1.2.14.jar)**. Otherwise, see [Installation & setup](SETUP.md). Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it.
<p align="center">
<a href="http://forthebadge.com/"><img src="https://forthebadge.com/images/badges/built-with-swag.svg" alt="forthebadge"/></a>
<a href="http://forthebadge.com/"><img src="https://forthebadge.com/images/badges/mom-made-pizza-rolls.svg" alt="forthebadge"/></a>
</p>
For 1.15.2, [click here](https://www.youtube.com/watch?v=j1qKtCZFURM) and see description. If you need Forge 1.15.2, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.5.3), follow the instructions, and get the `api-forge` jar.
A Minecraft pathfinder bot.
For 1.16.4, [click here](https://www.youtube.com/watch?v=_4eVJ9Qz2J8) and see description. If you need Forge 1.16.4, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.6.2) and get the `api-forge` jar.
[**Baritone Discord Server**](http://discord.gg/s6fRBAUpmr)
Baritone is the pathfinding system used in [Impact](https://impactclient.net/) since 4.4. There's a [showcase video](https://youtu.be/CZkLXWo4Fg4) made by @Adovin#0730 on Baritone which I recommend. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a (very old!) video I made showing off what it can do.
[Tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa)
The easiest way to install Baritone is to install [Impact](https://impactclient.net/), which comes with Baritone. The second easiest way (for 1.12.2 only) is to install the v1.2.* `api-forge` jar from [releases](https://github.com/cabaletta/baritone/releases). **For 1.12.2 Forge, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.2.15/baritone-api-forge-1.2.15.jar)**. Otherwise, see [Installation & setup](SETUP.md). Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it.
For 1.16.5, [click here](https://www.youtube.com/watch?v=_4eVJ9Qz2J8) and see description. If you need Forge or Fabric 1.16.5, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.6.3) and get the `api-forge` or `api-fabric` jar. **For 1.16.5 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.6.3/baritone-api-fabric-1.6.3.jar)**.
If you need Forge or Fabric 1.17.1, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.7.2) and get the `api-forge` or `api-fabric` jar. **For 1.17.1 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.7.2/baritone-api-fabric-1.7.2.jar)**.
If you need Forge or Fabric 1.18.2, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.8.3) and get the `api-forge` or `api-fabric` jar. **For 1.18.2 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.8.3/baritone-api-fabric-1.8.3.jar)**. **For 1.18.2 Forge, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.8.3/baritone-api-forge-1.8.3.jar)**.
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 through 1.16.4. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
the original version of the bot for Minecraft 1.8.9, rebuilt for 1.12.2 onwards. 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 from Aug 1, 2018, to Aug 1, 2019.
@@ -75,7 +95,7 @@ jar.
Below is an example of basic usage for changing some settings, and then pathing to an X/Z goal.
```
```java
BaritoneAPI.getSettings().allowSprint.value = true;
BaritoneAPI.getSettings().primaryTimeoutMS.value = 2000L;

View File

@@ -2,7 +2,7 @@
The easiest way to install Baritone is to install [Impact](https://impactclient.net/), which comes with Baritone.
You can also use a custom version json for Minecraft, with the [1.14.4](https://www.dropbox.com/s/rkml3hjokd3qv0m/1.14.4-Baritone.zip?dl=1) version or the [1.15.2](https://www.dropbox.com/s/8rx6f0kts9hvd4f/1.15.2-Baritone.zip?dl=1) version
You can also use a custom version json for Minecraft, with the [1.14.4](https://www.dropbox.com/s/rkml3hjokd3qv0m/1.14.4-Baritone.zip?dl=1) version or the [1.15.2](https://www.dropbox.com/s/8rx6f0kts9hvd4f/1.15.2-Baritone.zip?dl=1) version or the [1.16.5](https://www.dropbox.com/s/i6f292o2i7o9acp/1.16.5-Baritone.zip?dl=1) version.
Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it.
@@ -11,9 +11,9 @@ These releases are not always completely up to date with latest features, and ar
Link to the releases page: [Releases](https://github.com/cabaletta/baritone/releases)
v1.2.* is for 1.12.2, v1.3.* is for 1.13.2
v1.2.* is for 1.12.2, v1.3.* is for 1.13.2, v1.4.* is for 1.14.4, v1.5.* is for 1.15.2, v1.6.* is for 1.16.5, v1.7.* is for 1.17.1, v1.8.* is for 1.18.1
Any official release will be GPG signed by leijurv (44A3EA646EADAC6A) and ZeroMemes (73A788379A197567). Please verify that the hash of the file you download is in `checksums.txt` and that `checksums_signed.asc` is a valid signature by those two public keys of `checksums.txt`.
Any official release will be GPG signed by leijurv (44A3EA646EADAC6A). Please verify that the hash of the file you download is in `checksums.txt` and that `checksums_signed.asc` is a valid signature by that public keys of `checksums.txt`.
The build is fully deterministic and reproducible, and you can verify Travis did it properly by running `docker build --no-cache -t cabaletta/baritone .` yourself and comparing the shasum. This works identically on Travis, Mac, and Linux (if you have docker on Windows, I'd be grateful if you could let me know if it works there too).
@@ -22,20 +22,16 @@ The build is fully deterministic and reproducible, and you can verify Travis did
Building Baritone will result in 5 artifacts created in the ``dist`` directory. These are the same as the artifacts created in the [releases](https://github.com/cabaletta/baritone/releases).
**The Forge release can simply be added as a Forge mod.**
**The Forge and Fabric releases can simply be added as a Forge/Fabric mods.**
If another one of your Forge mods has a Baritone integration, you want `baritone-api-forge-VERSION.jar`. Otherwise, you want `baritone-standalone-forge-VERSION.jar`
- **API**: Only the non-api packages are obfuscated. This should be used in environments where other mods would like to use Baritone's features.
- **Forge API**: Same as API, but packaged for Forge. This should be used where another mod has a Baritone integration.
- **Forge/Fabric API**: Same as API, but packaged for Forge/Fabric. This should be used where another mod has a Baritone integration.
- **Standalone**: Everything is obfuscated. This should be used in environments where there are no other mods present that would like to use Baritone's features.
- **Forge Standalone**: Same as Standalone, but packaged for Forge. This should be used when Baritone is your only Forge mod, or none of your other Forge mods integrate with Baritone.
- **Forge/Fabric Standalone**: Same as Standalone, but packaged for Forge/Fabric. This should be used when Baritone is your only Forge/Fabric mod, or none of your other Forge/Fabric mods integrate with Baritone.
- **Unoptimized**: Nothing is obfuscated. This shouldn't be used ever in production.
## More Info
To replace out Impact 4.5's Baritone build with a customized one, build Baritone as above then copy & **rename** `dist/baritone-api-$VERSION$.jar` into `minecraft/libraries/cabaletta/baritone-api/1.2/baritone-api-1.2.jar`, replacing the jar that was previously there. You also need to edit `minecraft/versions/1.12.2-Impact_4.5/1.12.2-Impact_4.5.json`, find the line `"name": "cabaletta:baritone-api:1.2"`, remove the comma from the end, and **entirely remove the NEXT line** (starts with `"url"`). **Restart your launcher** then load as normal.
You can verify whether or not it worked by running `.b version` in chat (only valid in Impact). It should print out the version that you downloaded. Note: The version that comes with 4.5 is `v1.2.3`.
- **Forge/Fabric Unoptimized**: Same as Unoptimized, but packaged for Forge/Fabric.
## Build it yourself
- Clone or download Baritone
@@ -47,13 +43,13 @@ You can verify whether or not it worked by running `.b version` in chat (only va
## Command Line
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
If you have errors with a package missing please make sure you have setup your environment, and are using Oracle JDK 8.
If you have errors with a package missing please make sure you have setup your environment, and are using Oracle JDK 8 for 1.12.2-1.16.5, JDK 16 for 1.17.1, and JDK 17 for 1.18.1.
To check which java you are using do
`java -version` in a command prompt or terminal.
If you are using anything above OpenJDK 8, it might not work because the Java distributions above JDK 8 using may not have the needed javax classes.
If you are using anything above OpenJDK 8 for 1.12.2-1.16.5, it might not work because the Java distributions above JDK 8 using may not have the needed javax classes.
Open JDK 8 download: https://openjdk.java.net/install/
Open JDK download: https://openjdk.java.net/install/
#### macOS guide
In order to get JDK 8, Try running the following command:
`% /usr/libexec/java_home -V`
@@ -89,6 +85,12 @@ For minecraft 1.15.2+, run the following instead to include the Forge jars:
$ gradlew build -Pbaritone.forge_build
```
Do this instead for Fabric jars:
```
$ gradlew build -Pbaritone.fabric_build
```
Running Baritone:
```

View File

@@ -32,13 +32,13 @@ Watch this [showcase video](https://youtu.be/CZkLXWo4Fg4)!
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:
Commands in Baritone:
- `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 set a goal to a certain coordinate then path to it
- `goto x y z` or `goto x z` or `goto y` to go to a certain coordinate (in a single step, starts going immediately)
- `goal` to set the goal to your player's feet
- `goal clear` to clear the goal
- `cancel` or `stop` to stop everything
- `cancel` or `stop` to stop everything, `forcecancel` is also an option
- `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 iron_ore` to mine diamond ore or iron 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.) An amount of blocks can also be specified, for example, `mine 64 diamond_ore`.
- `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 select an area (`#help sel` to see what you can do with that selection).
@@ -47,15 +47,23 @@ Some common examples:
- `build` to build a schematic. `build blah.schematic` will load `schematics/blah.schematic` and build it with the origin being your player feet. `build blah.schematic 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).
- `schematica` to build the schematic that is currently open in schematica
- `tunnel` to dig and make a tunnel, 1x2. It will only deviate from the straight line if necessary such as to avoid lava. For a dumber tunnel that is really just cleararea, you can `tunnel 3 2 100`, to clear an area 3 high, 2 wide, and 100 deep.
- `farm` to automatically harvest, replant, or bone meal crops
- `farm` to automatically harvest, replant, or bone meal crops. Use `farm <range>` or `farm <range> <waypoint>` to limit the max distance from the starting point or a waypoint.
- `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.
- `come` tells Baritone to head towards your camera, useful when freecam doesn't move your player position.
- `blacklist` will stop baritone from going to the closest block so it won't attempt to get to it.
- `eta` to get information about the estimated time until the next segment and the goal, be aware that the ETA to your goal is really unprecise.
- `proc` to view miscellaneous information about the process currently controlling Baritone.
- `repack` to re-cache the chunks around you.
- `gc` to call `System.gc()` which may free up some memory.
- `render` to fix glitched chunk rendering without having to reload all of them.
- `reloadall` to reload Baritone's world cache or `saveall` to save Baritone's world cache.
- `find` to search through Baritone's cache and attempt to find the location of the block.
- `surface` or `top` to tell Baritone to head towards the closest surface-like area, this can be the surface or highest available air space.
- `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://baritone.leijurv.com/baritone/api/Settings.html).
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>.
There are about a hundred settings, but here are some fun / interesting / important ones that you might want to look at changing in normal usage of Baritone. The documentation for each can be found at the above links.

View File

@@ -16,7 +16,7 @@
*/
group 'baritone'
version '1.2.14'
version '1.2.16'
buildscript {
repositories {
@@ -42,6 +42,7 @@ import baritone.gradle.task.CreateDistTask
import baritone.gradle.task.ProguardTask
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'net.minecraftforge.gradle.tweaker-client'
apply plugin: 'org.spongepowered.mixin'
@@ -144,3 +145,25 @@ task proguard(type: ProguardTask) {
task createDist(type: CreateDistTask, dependsOn: proguard)
build.finalizedBy(createDist)
install {
def jarApiName = String.format("%s-api-%s", rootProject.name, version.toString())
def jarApiForgeName = String.format("%s-api-forge-%s", rootProject.name, version.toString())
def jarSAName = String.format("%s-standalone-%s", rootProject.name, version.toString())
def jarSAForgeName = String.format("%s-standalone-forge-%s", rootProject.name, version.toString())
artifacts {
archives file("$buildDir/libs/"+jarApiName+".jar")
archives file("$buildDir/libs/"+jarApiForgeName+".jar")
archives file("$buildDir/libs/"+jarSAName+".jar")
archives file("$buildDir/libs/"+jarSAForgeName+".jar")
}
repositories.mavenInstaller {
addFilter('api') { artifact, file -> artifact.name == "baritone-api" }
addFilter('api-forge') { artifact, file -> artifact.name == "baritone-api-forge" }
addFilter('standalone') { artifact, file -> artifact.name == "baritone-standalone" }
addFilter('standalone-forge') { artifact, file -> artifact.name == "baritone-standalone-forge" }
}
}
install.dependsOn(build)

View File

@@ -209,8 +209,8 @@ public class ProguardTask extends BaritoneGradleTask {
// Setup the template that will be used to derive the API and Standalone configs
List<String> template = Files.readAllLines(getTemporaryFile(PROGUARD_CONFIG_DEST));
template.add(0, "-injars " + this.artifactPath.toString());
template.add(1, "-outjars " + this.getTemporaryFile(PROGUARD_EXPORT_PATH));
template.add(0, "-injars '" + this.artifactPath.toString() + "'");
template.add(1, "-outjars '" + this.getTemporaryFile(PROGUARD_EXPORT_PATH) + "'");
// Acquire the RT jar using "java -verbose". This doesn't work on Java 9+
Process p = new ProcessBuilder(this.getJavaBinPathForProguard(), "-verbose").start();
@@ -405,9 +405,15 @@ public class ProguardTask extends BaritoneGradleTask {
Files.delete(this.proguardOut);
}
Path proguardJar = getTemporaryFile(PROGUARD_JAR);
// Make paths relative to work directory; fixes spaces in path to config, @"" doesn't work
Path workingDirectory = getTemporaryFile("");
Path proguardJar = workingDirectory.relativize(getTemporaryFile(PROGUARD_JAR));
config = workingDirectory.relativize(config);
// Honestly, if you still have spaces in your path at this point, you're SOL.
Process p = new ProcessBuilder("java", "-jar", proguardJar.toString(), "@" + config.toString())
.directory(getTemporaryFile("").toFile()) // Set the working directory to the temporary folder]
.directory(workingDirectory.toFile()) // Set the working directory to the temporary folder]
.start();
// We can't do output inherit process I/O with gradle for some reason and have it work, so we have to do this

View File

@@ -1,5 +1,6 @@
-keepattributes Signature
-keepattributes *Annotation*
-keepattributes InnerClasses
-optimizationpasses 5
-verbose
@@ -22,6 +23,7 @@
-keep class baritone.api.IBaritoneProvider
-keep class baritone.api.utils.MyChunkPos { *; } # even in standalone we need to keep this for gson reflect
-keepname class baritone.api.utils.BlockOptionalMeta # this name is exposed to the user, so we need to keep it in all builds
# Keep any class or member annotated with @KeepName so we dont have to put everything in the script
-keep,allowobfuscation @interface baritone.KeepName
@@ -40,8 +42,10 @@
#try to keep usage of schematica in separate classes
-keep class baritone.utils.schematic.schematica.**
-keep class baritone.utils.schematic.litematica.**
#proguard doesnt like it when it cant find our fake schematica classes
-dontwarn baritone.utils.schematic.schematica.**
-dontwarn baritone.utils.schematic.litematica.**
# copy all necessary libraries into tempLibraries to build
@@ -81,7 +85,7 @@
-libraryjars 'tempLibraries/netty-all-4.1.9.Final.jar'
-libraryjars 'tempLibraries/oshi-core-1.1.jar'
-libraryjars 'tempLibraries/patchy-1.1.jar'
-libraryjars 'tempLibraries/patchy-1.3.9.jar'
-libraryjars 'tempLibraries/platform-3.4.0.jar'
-libraryjars 'tempLibraries/realms-1.10.22.jar'
-libraryjars 'tempLibraries/soundsystem-20120107.jar'
@@ -381,3 +385,5 @@
public java.lang.String substring(int);
public java.lang.String substring(int,int);
}
-printmapping mapping.txt

View File

@@ -17,8 +17,10 @@
package baritone.api;
import baritone.api.utils.NotificationHelper;
import baritone.api.utils.SettingsUtil;
import baritone.api.utils.TypeUtils;
import baritone.api.utils.gui.BaritoneToast;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.init.Blocks;
@@ -32,6 +34,7 @@ import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**
@@ -46,6 +49,11 @@ public final class Settings {
*/
public final Setting<Boolean> allowBreak = new Setting<>(true);
/**
* Blocks that baritone will be allowed to break even with allowBreak set to false
*/
public final Setting<List<Block>> allowBreakAnyway = new Setting<>(new ArrayList<>());
/**
* Allow Baritone to sprint
*/
@@ -70,9 +78,9 @@ public final class Settings {
public final Setting<Boolean> assumeExternalAutoTool = new Setting<>(false);
/**
* If this setting is on, no auto tool will occur at all, not at calculation time nor execution time
* Automatically select the best available tool
*/
public final Setting<Boolean> disableAutoTool = new Setting<>(false);
public final Setting<Boolean> autoTool = new Setting<>(true);
/**
* It doesn't actually take twenty ticks to place a block, this cost is so high
@@ -99,6 +107,13 @@ public final class Settings {
*/
public final Setting<Double> walkOnWaterOnePenalty = new Setting<>(3D);
/**
* Don't allow breaking blocks next to liquids.
* <p>
* Enable if you have mods adding custom fluid physics.
*/
public final Setting<Boolean> strictLiquidCheck = new Setting<>(false);
/**
* Allow Baritone to fall arbitrary distances and place a water bucket beneath it.
* Reliability: questionable.
@@ -108,6 +123,8 @@ public final class Settings {
/**
* Allow Baritone to assume it can walk on still water just like any other block.
* This functionality is assumed to be provided by a separate library that might have imported Baritone.
* <p>
* Note: This will prevent some usage of the frostwalker enchantment, like pillaring up from water.
*/
public final Setting<Boolean> assumeWalkOnWater = new Setting<>(false);
@@ -187,6 +204,13 @@ public final class Settings {
/**
* Blocks that Baritone is not allowed to break
*/
public final Setting<List<Block>> blocksToDisallowBreaking = new Setting<>(new ArrayList<>(
// Leave Empty by Default
));
/**
* blocks that baritone shouldn't break, but can if it needs to.
*/
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,
@@ -197,6 +221,11 @@ public final class Settings {
Blocks.WALL_SIGN
)));
/**
* this multiplies the break speed, if set above 1 it's "encourage breaking" instead
*/
public final Setting<Double> avoidBreakingMultiplier = new Setting<>(.1);
/**
* A list of blocks to be treated as if they're air.
* <p>
@@ -206,6 +235,40 @@ public final class Settings {
)));
/**
* A list of blocks to be treated as correct.
* <p>
* If a schematic asks for any block on this list at a certain position, it will be treated as correct, regardless of what it currently is.
*/
public final Setting<List<Block>> buildSkipBlocks = new Setting<>(new ArrayList<>(Arrays.asList(
)));
/**
* A mapping of blocks to blocks treated as correct in their position
* <p>
* If a schematic asks for a block on this mapping, all blocks on the mapped list will be accepted at that location as well
* <p>
* Syntax same as <a href="https://baritone.leijurv.com/baritone/api/Settings.html#buildSubstitutes">buildSubstitutes</a>
*/
public final Setting<Map<Block, List<Block>>> buildValidSubstitutes = new Setting<>(new HashMap<>());
/**
* A mapping of blocks to blocks to be built instead
* <p>
* If a schematic asks for a block on this mapping, Baritone will place the first placeable block in the mapped list
* <p>
* Usage Syntax:
* <pre>
* sourceblockA->blockToSubstituteA1,blockToSubstituteA2,...blockToSubstituteAN,sourceBlockB->blockToSubstituteB1,blockToSubstituteB2,...blockToSubstituteBN,...sourceBlockX->blockToSubstituteX1,blockToSubstituteX2...blockToSubstituteXN
* </pre>
* Example:
* <pre>
* stone->cobblestone,andesite,oak_planks->birch_planks,acacia_planks,glass
* </pre>
*/
public final Setting<Map<Block, List<Block>>> buildSubstitutes = new Setting<>(new HashMap<>());
/**
* A list of blocks to become air
* <p>
@@ -220,6 +283,17 @@ public final class Settings {
*/
public final Setting<Boolean> buildIgnoreExisting = new Setting<>(false);
/**
* If this is true, the builder will ignore directionality of certain blocks like glazed terracotta.
*/
public final Setting<Boolean> buildIgnoreDirection = new Setting<>(false);
/**
* A list of names of block properties the builder will ignore.
*/
public final Setting<List<String>> buildIgnoreProperties = new Setting<>(new ArrayList<>(Arrays.asList(
)));
/**
* If this setting is true, Baritone will never break a block that is adjacent to an unsupported falling block.
* <p>
@@ -342,6 +416,9 @@ public final class Settings {
*/
public final Setting<Double> mobSpawnerAvoidanceCoefficient = new Setting<>(2.0);
/**
* Distance to avoid mob spawners.
*/
public final Setting<Integer> mobSpawnerAvoidanceRadius = new Setting<>(16);
/**
@@ -351,6 +428,9 @@ public final class Settings {
*/
public final Setting<Double> mobAvoidanceCoefficient = new Setting<>(1.5);
/**
* Distance to avoid mobs.
*/
public final Setting<Integer> mobAvoidanceRadius = new Setting<>(8);
/**
@@ -501,6 +581,17 @@ public final class Settings {
*/
public final Setting<Long> slowPathTimeoutMS = new Setting<>(40000L);
/**
* allows baritone to save bed waypoints when interacting with beds
*/
public final Setting<Boolean> doBedWaypoints = new Setting<>(true);
/**
* allows baritone to save death waypoints
*/
public final Setting<Boolean> doDeathWaypoints = new Setting<>(true);
/**
* The big one. Download all chunks in simplified 2-bit format and save them for better very-long-distance pathing.
*/
@@ -517,13 +608,6 @@ public final class Settings {
*/
public final Setting<Boolean> pruneRegionsFromRAM = new Setting<>(true);
/**
* Remember the contents of containers (chests, echests, furnaces)
* <p>
* Really buggy since the packet stuff is multithreaded badly thanks to brady
*/
public final Setting<Boolean> containerMemory = new Setting<>(false);
/**
* Fill in blocks behind you
*/
@@ -572,6 +656,12 @@ public final class Settings {
*/
public final Setting<Boolean> renderGoal = new Setting<>(true);
/**
* Render the goal as a sick animated thingy instead of just a box
* (also controls animation of GoalXZ if {@link #renderGoalXZBeacon} is enabled)
*/
public final Setting<Boolean> renderGoalAnimated = new Setting<>(true);
/**
* Render selection boxes
*/
@@ -641,7 +731,7 @@ public final class Settings {
/**
* When GetToBlockProcess or MineProcess fails to calculate a path, instead of just giving up, mark the closest instance
* of that block as "unreachable" and go towards the next closest. GetToBlock expands this seaarch to the whole "vein"; MineProcess does not.
* of that block as "unreachable" and go towards the next closest. GetToBlock expands this search to the whole "vein"; MineProcess does not.
* This is because MineProcess finds individual impossible blocks (like one block in a vein that has gravel on top then lava, so it can't break)
* Whereas GetToBlock should blacklist the whole "vein" if it can't get to any of them.
*/
@@ -696,6 +786,16 @@ public final class Settings {
*/
public final Setting<Boolean> censorRanCommands = new Setting<>(false);
/**
* Stop using tools just before they are going to break.
*/
public final Setting<Boolean> itemSaver = new Setting<>(false);
/**
* Durability to leave on the tool when using itemSaver
*/
public final Setting<Integer> itemSaverThreshold = new Setting<>(10);
/**
* Always prefer silk touch tools over regular tools. This will not sacrifice speed, but it will always prefer silk
* touch tools over other tools of the same speed. This includes always choosing ANY silk touch tool over your hand.
@@ -756,7 +856,7 @@ public final class Settings {
public final Setting<Integer> allowOnlyExposedOresDistance = new Setting<>(1);
/**
* When GetToBlock doesn't know any locations for the desired block, explore randomly instead of giving up.
* When GetToBlock or non-legit Mine doesn't know any locations for the desired block, explore randomly instead of giving up.
*/
public final Setting<Boolean> exploreForBlocks = new Setting<>(true);
@@ -808,6 +908,11 @@ public final class Settings {
*/
public final Setting<Boolean> layerOrder = new Setting<>(false);
/**
* How high should the individual layers be?
*/
public final Setting<Integer> layerHeight = new Setting<>(1);
/**
* Start building the schematic at a specific layer.
* Can help on larger builds when schematic wants to break things its already built
@@ -819,6 +924,11 @@ public final class Settings {
*/
public final Setting<Boolean> skipFailedLayers = new Setting<>(false);
/**
* Only build the selected part of schematics
*/
public final Setting<Boolean> buildOnlySelection = 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
*/
@@ -829,6 +939,13 @@ public final class Settings {
*/
public final Setting<Integer> buildRepeatCount = new Setting<>(-1);
/**
* Don't notify schematics that they are moved.
* e.g. replacing will replace the same spots for every repetition
* Mainly for backward compatibility.
*/
public final Setting<Boolean> buildRepeatSneaky = new Setting<>(true);
/**
* Allow standing above a block while mining it, in BuilderProcess
* <p>
@@ -937,6 +1054,7 @@ public final class Settings {
* Disallow MineBehavior from using X-Ray to see where the ores are. Turn this option on to force it to mine "legit"
* where it will only mine an ore once it can actually see it, so it won't do or know anything that a normal player
* couldn't. If you don't want it to look like you're X-Raying, turn this on
* This will always explore, regardless of exploreForBlocks
*/
public final Setting<Boolean> legitMine = new Setting<>(false);
@@ -1021,7 +1139,21 @@ 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<>(msg -> Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(msg));
/**
* The function that is called when Baritone will send a desktop notification. This function can be added to
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
* {@link Setting#value};
*/
public final Setting<BiConsumer<String, Boolean>> notifier = new Setting<>(NotificationHelper::notify);
/**
* The function that is called when Baritone will show a toast. This function can be added to
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
* {@link Setting#value};
*/
public final Setting<BiConsumer<ITextComponent, ITextComponent>> toaster = new Setting<>(BaritoneToast::addOrUpdate);
/**
* The size of the box that is rendered when the current goal is a GoalYLevel
@@ -1113,6 +1245,11 @@ public final class Settings {
*/
public final Setting<Boolean> renderSelectionCorners = new Setting<>(true);
/**
* Use sword to mine.
*/
public final Setting<Boolean> useSwordToMine = new Setting<>(true);
/**
* Desktop notifications
*/

View File

@@ -58,6 +58,15 @@ public interface IPathingBehavior extends IBehavior {
return Optional.of(current.getPath().ticksRemainingFrom(start));
}
/**
* Returns the estimated remaining ticks to the current goal.
* Given that the return type is an optional, {@link Optional#empty()}
* will be returned in the case that there is no current goal.
*
* @return The estimated remaining ticks to the current goal.
*/
Optional<Double> estimatedTicksToGoal();
/**
* @return The current pathing goal
*/

View File

@@ -37,9 +37,4 @@ public interface IWorldData {
*/
IWaypointCollection getWaypoints();
/**
* @return The {@link IContainerMemory} instance
* @see IContainerMemory
*/
IContainerMemory getContainerMemory();
}

View File

@@ -26,7 +26,8 @@ import java.util.stream.Stream;
public enum RelativeCoordinate implements IDatatypePost<Double, Double> {
INSTANCE;
private static Pattern PATTERN = Pattern.compile("^(~?)([+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)([k-k]?)|)$");
private static String ScalesAliasRegex = "[kKmM]";
private static Pattern PATTERN = Pattern.compile("^(~?)([+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)("+ScalesAliasRegex+"?)|)$");
@Override
public Double apply(IDatatypeContext ctx, Double origin) throws CommandException {
@@ -41,11 +42,15 @@ public enum RelativeCoordinate implements IDatatypePost<Double, Double> {
boolean isRelative = !matcher.group(1).isEmpty();
double offset = matcher.group(2).isEmpty() ? 0 : Double.parseDouble(matcher.group(2).replaceAll("k", ""));
if (matcher.group(2).contains("k")) {
double offset = matcher.group(2).isEmpty() ? 0 : Double.parseDouble(matcher.group(2).replaceAll(ScalesAliasRegex, ""));
if (matcher.group(2).toLowerCase().contains("k")) {
offset *= 1000;
}
if (matcher.group(2).toLowerCase().contains("m")) {
offset *= 1000000;
}
if (isRelative) {
return origin + offset;

View File

@@ -253,8 +253,8 @@ public class TabCompleteHelper {
public TabCompleteHelper addSettings() {
return append(
BaritoneAPI.getSettings().allSettings.stream()
.filter(s -> !SettingsUtil.javaOnlySetting(s))
.map(Settings.Setting::getName)
.filter(s -> !s.equalsIgnoreCase("logger"))
.sorted(String.CASE_INSENSITIVE_ORDER)
);
}

View File

@@ -84,7 +84,7 @@ public class Registry<V> {
* @param entry The entry to unregister.
*/
public void unregister(V entry) {
if (registered(entry)) {
if (!registered(entry)) {
return;
}
_entries.remove(entry);

View File

@@ -54,4 +54,18 @@ public interface Goal {
default double heuristic(BlockPos pos) {
return heuristic(pos.getX(), pos.getY(), pos.getZ());
}
/**
* Returns the heuristic at the goal.
* i.e. {@code heuristic() == heuristic(x,y,z)}
* when {@code isInGoal(x,y,z) == true}
* This is needed by {@code PathingBehavior#estimatedTicksToGoal} because
* some Goals actually do not have a heuristic of 0 when that condition is met
*
* @return The estimate number of ticks to satisfy the goal when the goal
* is already satisfied
*/
default double heuristic() {
return 0;
}
}

View File

@@ -87,9 +87,9 @@ public class GoalBlock implements Goal, IGoalRenderPos {
public static double calculate(double xDiff, int yDiff, double zDiff) {
double heuristic = 0;
// if yDiff is 1 that means that pos.getY()-this.y==1 which means that we're 1 block below where we should be
// therefore going from 0,0,0 to a GoalYLevel of pos.getY()-this.y is accurate
heuristic += GoalYLevel.calculate(yDiff, 0);
// if yDiff is 1 that means that currentY-goalY==1 which means that we're 1 block above where we should be
// therefore going from 0,yDiff,0 to a GoalYLevel of 0 is accurate
heuristic += GoalYLevel.calculate(0, yDiff);
//use the pythagorean and manhattan mixture from GoalXZ
heuristic += GoalXZ.calculate(xDiff, zDiff);

View File

@@ -57,6 +57,16 @@ public class GoalComposite implements Goal {
return min;
}
@Override
public double heuristic() {
double min = Double.MAX_VALUE;
for (Goal g : goals) {
// just take the highest value that is guaranteed to be inside the goal
min = Math.min(min, g.heuristic());
}
return min;
}
@Override
public String toString() {
return "GoalComposite" + Arrays.toString(goals);

View File

@@ -45,6 +45,11 @@ public class GoalInverted implements Goal {
return -origin.heuristic(x, y, z);
}
@Override
public double heuristic() {
return Double.NEGATIVE_INFINITY;
}
@Override
public String toString() {
return String.format("GoalInverted{%s}", origin.toString());

View File

@@ -19,6 +19,8 @@ package baritone.api.pathing.goals;
import baritone.api.utils.SettingsUtil;
import baritone.api.utils.interfaces.IGoalRenderPos;
import it.unimi.dsi.fastutil.doubles.DoubleOpenHashSet;
import it.unimi.dsi.fastutil.doubles.DoubleIterator;
import net.minecraft.util.math.BlockPos;
public class GoalNear implements Goal, IGoalRenderPos {
@@ -51,6 +53,34 @@ public class GoalNear implements Goal, IGoalRenderPos {
return GoalBlock.calculate(xDiff, yDiff, zDiff);
}
@Override
public double heuristic() {// TODO less hacky solution
int range = (int) Math.ceil(Math.sqrt(rangeSq));
DoubleOpenHashSet maybeAlwaysInside = new DoubleOpenHashSet(); // see pull request #1978
double minOutside = Double.POSITIVE_INFINITY;
for (int dx = -range; dx <= range; dx++) {
for (int dy = -range; dy <= range; dy++) {
for (int dz = -range; dz <= range; dz++) {
double h = heuristic(x + dx, y + dy, z + dz);
if (h < minOutside && isInGoal(x + dx, y + dy, z + dz)) {
maybeAlwaysInside.add(h);
} else {
minOutside = Math.min(minOutside, h);
}
}
}
}
double maxInside = Double.NEGATIVE_INFINITY;
DoubleIterator it = maybeAlwaysInside.iterator();
while (it.hasNext()) {
double inside = it.nextDouble();
if (inside < minOutside) {
maxInside = Math.max(maxInside, inside);
}
}
return maxInside;
}
@Override
public BlockPos getGoalPos() {
return new BlockPos(x, y, z);

View File

@@ -18,6 +18,8 @@
package baritone.api.pathing.goals;
import baritone.api.utils.SettingsUtil;
import it.unimi.dsi.fastutil.doubles.DoubleOpenHashSet;
import it.unimi.dsi.fastutil.doubles.DoubleIterator;
import net.minecraft.util.math.BlockPos;
import java.util.Arrays;
@@ -65,7 +67,7 @@ public class GoalRunAway implements Goal {
}
@Override
public double heuristic(int x, int y, int z) {//mostly copied from GoalBlock
public double heuristic(int x, int y, int z) {// mostly copied from GoalBlock
double min = Double.MAX_VALUE;
for (BlockPos p : from) {
double h = GoalXZ.calculate(p.getX() - x, p.getZ() - z);
@@ -80,6 +82,48 @@ public class GoalRunAway implements Goal {
return min;
}
@Override
public double heuristic() {// TODO less hacky solution
int distance = (int) Math.ceil(Math.sqrt(distanceSq));
int minX = Integer.MAX_VALUE;
int minY = Integer.MAX_VALUE;
int minZ = Integer.MAX_VALUE;
int maxX = Integer.MIN_VALUE;
int maxY = Integer.MIN_VALUE;
int maxZ = Integer.MIN_VALUE;
for (BlockPos p : from) {
minX = Math.min(minX, p.getX() - distance);
minY = Math.min(minY, p.getY() - distance);
minZ = Math.min(minZ, p.getZ() - distance);
maxX = Math.max(minX, p.getX() + distance);
maxY = Math.max(minY, p.getY() + distance);
maxZ = Math.max(minZ, p.getZ() + distance);
}
DoubleOpenHashSet maybeAlwaysInside = new DoubleOpenHashSet(); // see pull request #1978
double minOutside = Double.POSITIVE_INFINITY;
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
for (int z = minZ; z <= maxZ; z++) {
double h = heuristic(x, y, z);
if (h < minOutside && isInGoal(x, y, z)) {
maybeAlwaysInside.add(h);
} else {
minOutside = Math.min(minOutside, h);
}
}
}
}
double maxInside = Double.NEGATIVE_INFINITY;
DoubleIterator it = maybeAlwaysInside.iterator();
while (it.hasNext()) {
double inside = it.nextDouble();
if (inside < minOutside) {
maxInside = Math.max(maxInside, inside);
}
}
return maxInside;
}
@Override
public String toString() {
if (maintainY != null) {

View File

@@ -64,6 +64,11 @@ public class GoalStrictDirection implements Goal {
return heuristic;
}
@Override
public double heuristic() {
return Double.NEGATIVE_INFINITY;
}
@Override
public String toString() {
return String.format(

View File

@@ -58,6 +58,8 @@ public interface IBuilderProcess extends IBaritoneProcess {
void buildOpenSchematic();
void buildOpenLitematic(int i);
void pause();
boolean isPaused();

View File

@@ -71,4 +71,11 @@ public class CompositeSchematic extends AbstractSchematic {
}
return entry.schematic.desiredState(x - entry.x, y - entry.y, z - entry.z, current, approxPlaceable);
}
@Override
public void reset() {
for (CompositeSchematicEntry entry : schematicArr) {
entry.schematic.reset();
}
}
}

View File

@@ -19,7 +19,6 @@ package baritone.api.schematic;
import baritone.api.utils.BlockOptionalMeta;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import java.util.List;
@@ -44,8 +43,6 @@ public class FillSchematic extends AbstractSchematic {
public IBlockState desiredState(int x, int y, int z, IBlockState current, List<IBlockState> approxPlaceable) {
if (bom.matches(current)) {
return current;
} else if (current.getBlock() != Blocks.AIR) {
return Blocks.AIR.getDefaultState();
}
for (IBlockState placeable : approxPlaceable) {
if (bom.matches(placeable)) {

View File

@@ -73,6 +73,11 @@ public interface ISchematic {
*/
IBlockState desiredState(int x, int y, int z, IBlockState current, List<IBlockState> approxPlaceable);
/**
* Resets possible caches to avoid wrong behavior when moving the schematic around
*/
default void reset() {}
/**
* @return The width (X axis length) of this schematic
*/

View File

@@ -31,6 +31,18 @@ public class ReplaceSchematic extends MaskSchematic {
this.cache = new Boolean[widthX()][heightY()][lengthZ()];
}
@Override
public void reset() {
// it's final, can't use this.cache = new Boolean[widthX()][heightY()][lengthZ()]
for (int x = 0; x < cache.length; x++) {
for (int y = 0; y < cache[0].length; y++) {
for (int z = 0; z < cache[0][0].length; z++) {
cache[x][y][z] = null;
}
}
}
}
@Override
protected boolean partOfMask(int x, int y, int z, IBlockState currentState) {
if (cache[x][y][z] == null) {

View File

@@ -0,0 +1,89 @@
/*
* 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.schematic;
import net.minecraft.block.Block;
import net.minecraft.block.BlockAir;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SubstituteSchematic extends AbstractSchematic {
private final ISchematic schematic;
private final Map<Block, List<Block>> substitutions;
private final Map<IBlockState, Map<Block, IBlockState>> blockStateCache = new HashMap<>();
public SubstituteSchematic(ISchematic schematic, Map<Block,List<Block>> substitutions) {
super(schematic.widthX(), schematic.heightY(), schematic.lengthZ());
this.schematic = schematic;
this.substitutions = substitutions;
}
@Override
public boolean inSchematic(int x, int y, int z, IBlockState currentState) {
return schematic.inSchematic(x, y, z, currentState);
}
@Override
public IBlockState desiredState(int x, int y, int z, IBlockState current, List<IBlockState> approxPlaceable) {
IBlockState desired = schematic.desiredState(x, y, z, current, approxPlaceable);
Block desiredBlock = desired.getBlock();
if (!substitutions.containsKey(desiredBlock)) {
return desired;
}
List<Block> substitutes = substitutions.get(desiredBlock);
if (substitutes.contains(current.getBlock()) && !(current.getBlock() instanceof BlockAir)) {// don't preserve air, it's almost always there and almost never wanted
return withBlock(desired, current.getBlock());
}
for (Block substitute : substitutes) {
if (substitute instanceof BlockAir) {
return current.getBlock() instanceof BlockAir ? current : Blocks.AIR.getDefaultState(); // can always "place" air
}
for (IBlockState placeable : approxPlaceable) {
if (substitute.equals(placeable.getBlock())) {
return withBlock(desired, placeable.getBlock());
}
}
}
return substitutes.get(0).getDefaultState();
}
private IBlockState withBlock(IBlockState state, Block block) {
if (blockStateCache.containsKey(state) && blockStateCache.get(state).containsKey(block)) {
return blockStateCache.get(state).get(block);
}
Collection<IProperty<?>> properties = state.getPropertyKeys();
IBlockState newState = block.getDefaultState();
for (IProperty<?> property : properties) {
try {
newState = copySingleProp(state, newState, property);
} catch (IllegalArgumentException e) { //property does not exist for target block
}
}
blockStateCache.computeIfAbsent(state, s -> new HashMap<Block,IBlockState>()).put(block, newState);
return newState;
}
private <T extends Comparable<T>> IBlockState copySingleProp(IBlockState fromState, IBlockState toState, IProperty<T> prop) {
return toState.withProperty(prop, fromState.getValue(prop));
}
}

View File

@@ -18,7 +18,6 @@
package baritone.api.utils;
import baritone.api.BaritoneAPI;
import baritone.api.utils.gui.BaritoneToast;
import net.minecraft.client.Minecraft;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
@@ -71,7 +70,7 @@ public interface Helper {
* @param message The message to display in the popup
*/
default void logToast(ITextComponent title, ITextComponent message) {
mc.addScheduledTask(() -> BaritoneToast.addOrUpdate(mc.getToastGui(), title, message, BaritoneAPI.getSettings().toastTimer.value));
mc.addScheduledTask(() -> BaritoneAPI.getSettings().toaster.value.accept(title, message));
}
/**
@@ -93,6 +92,48 @@ public interface Helper {
logToast(Helper.getPrefix(), new TextComponentString(message));
}
/**
* Send a message as a desktop notification
*
* @param message The message to display in the notification
*/
default void logNotification(String message) {
logNotification(message, false);
}
/**
* Send a message as a desktop notification
*
* @param message The message to display in the notification
* @param error Whether to log as an error
*/
default void logNotification(String message, boolean error) {
if (BaritoneAPI.getSettings().desktopNotifications.value) {
logNotificationDirect(message, error);
}
}
/**
* Send a message as a desktop notification regardless of desktopNotifications
* (should only be used for critically important messages)
*
* @param message The message to display in the notification
*/
default void logNotificationDirect(String message) {
logNotificationDirect(message, false);
}
/**
* Send a message as a desktop notification regardless of desktopNotifications
* (should only be used for critically important messages)
*
* @param message The message to display in the notification
* @param error Whether to log as an error
*/
default void logNotificationDirect(String message, boolean error) {
mc.addScheduledTask(() -> BaritoneAPI.getSettings().notifier.value.accept(message, error));
}
/**
* Send a message to chat only if chatDebug is on
*

View File

@@ -15,7 +15,7 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.utils;
package baritone.api.utils;
import org.apache.commons.lang3.SystemUtils;

View File

@@ -35,6 +35,7 @@ import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -49,6 +50,7 @@ public class SettingsUtil {
private static final Path SETTINGS_PATH = getMinecraft().gameDir.toPath().resolve("baritone").resolve("settings.txt");
private static final Pattern SETTING_PATTERN = Pattern.compile("^(?<setting>[^ ]+) +(?<value>.+)"); // key and value split by the first space
private static final String[] JAVA_ONLY_SETTINGS = {"logger", "notifier", "toaster"};
private static boolean isComment(String line) {
return line.startsWith("#") || line.startsWith("//");
@@ -110,7 +112,7 @@ public class SettingsUtil {
System.out.println("NULL SETTING?" + setting.getName());
continue;
}
if (setting.getName().equals("logger")) {
if (javaOnlySetting(setting)) {
continue; // NO
}
if (setting.value == setting.defaultValue) {
@@ -164,13 +166,28 @@ public class SettingsUtil {
}
public static String settingToString(Settings.Setting setting) throws IllegalStateException {
if (setting.getName().equals("logger")) {
return "logger";
if (javaOnlySetting(setting)) {
return setting.getName();
}
return setting.getName() + " " + settingValueToString(setting);
}
/**
* This should always be the same as whether the setting can be parsed from or serialized to a string
*
* @param setting The Setting
* @return true if the setting can not be set or read by the user
*/
public static boolean javaOnlySetting(Settings.Setting setting) {
for (String name : JAVA_ONLY_SETTINGS) { // no JAVA_ONLY_SETTINGS.contains(...) because that would be case sensitive
if (setting.getName().equalsIgnoreCase(name)) {
return true;
}
}
return false;
}
public static void parseAndApply(Settings settings, String settingName, String settingValue) throws IllegalStateException, NumberFormatException {
Settings.Setting setting = settings.byLowerName.get(settingName);
if (setting == null) {
@@ -261,6 +278,36 @@ public class SettingsUtil {
public boolean accepts(Type type) {
return List.class.isAssignableFrom(TypeUtils.resolveBaseClass(type));
}
},
MAPPING() {
@Override
public Object parse(ParserContext context, String raw) {
Type keyType = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
Type valueType = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[1];
Parser keyParser = Parser.getParser(keyType);
Parser valueParser = Parser.getParser(valueType);
return Stream.of(raw.split(",(?=[^,]*->)"))
.map(s -> s.split("->"))
.collect(Collectors.toMap(s -> keyParser.parse(context, s[0]), s -> valueParser.parse(context, s[1])));
}
@Override
public String toString(ParserContext context, Object value) {
Type keyType = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
Type valueType = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[1];
Parser keyParser = Parser.getParser(keyType);
Parser valueParser = Parser.getParser(valueType);
return ((Map<?,?>) value).entrySet().stream()
.map(o -> keyParser.toString(context, o.getKey()) + "->" + valueParser.toString(context, o.getValue()))
.collect(Collectors.joining(","));
}
@Override
public boolean accepts(Type type) {
return Map.class.isAssignableFrom(TypeUtils.resolveBaseClass(type));
}
};
private final Class<?> cla$$;

View File

@@ -71,4 +71,8 @@ public class BaritoneToast implements IToast {
baritonetoast.setDisplayedText(title, subtitle);
}
}
public static void addOrUpdate(ITextComponent title, ITextComponent subtitle) {
addOrUpdate(net.minecraft.client.Minecraft.getMinecraft().getToastGui(), title, subtitle, baritone.api.BaritoneAPI.getSettings().toastTimer.value);
}
}

View File

@@ -0,0 +1,35 @@
/*
* 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.utils.accessor.IItemTool;
import net.minecraft.item.Item;
import net.minecraft.item.ItemTool;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(ItemTool.class)
public class MixinItemTool implements IItemTool {
@Shadow protected Item.ToolMaterial toolMaterial;
@Override
public int getHarvestLevel() {
return toolMaterial.getHarvestLevel();
}
}

View File

@@ -0,0 +1,35 @@
/*
* 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.utils.accessor.INBTTagLongArray;
import net.minecraft.nbt.NBTTagLongArray;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
/**
* @author rycbar
* @since 26.09.2022
*/
@Mixin(NBTTagLongArray.class)
public abstract class MixinNBTTagLongArray implements INBTTagLongArray {
@Accessor("data")
@Override
public abstract long[] getLongArray();
}

View File

@@ -21,7 +21,9 @@
"MixinEntityRenderer",
"MixinGuiScreen",
"MixinItemStack",
"MixinItemTool",
"MixinMinecraft",
"MixinNBTTagLongArray",
"MixinNetHandlerPlayClient",
"MixinNetworkManager",
"MixinPlayerControllerMP",

View File

@@ -68,8 +68,8 @@ public class Baritone implements IBaritone {
private PathingBehavior pathingBehavior;
private LookBehavior lookBehavior;
private MemoryBehavior memoryBehavior;
private InventoryBehavior inventoryBehavior;
private WaypointBehavior waypointBehavior;
private InputOverrideHandler inputOverrideHandler;
private FollowProcess followProcess;
@@ -100,9 +100,9 @@ public class Baritone implements IBaritone {
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
pathingBehavior = new PathingBehavior(this);
lookBehavior = new LookBehavior(this);
memoryBehavior = new MemoryBehavior(this);
inventoryBehavior = new InventoryBehavior(this);
inputOverrideHandler = new InputOverrideHandler(this);
waypointBehavior = new WaypointBehavior(this);
}
this.pathingControlManager = new PathingControlManager(this);
@@ -151,10 +151,6 @@ public class Baritone implements IBaritone {
return this.playerContext;
}
public MemoryBehavior getMemoryBehavior() {
return this.memoryBehavior;
}
@Override
public FollowProcess getFollowProcess() {
return this.followProcess;

View File

@@ -18,6 +18,7 @@
package baritone.behavior;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.event.events.TickEvent;
import baritone.utils.ToolSet;
import net.minecraft.block.Block;
@@ -112,6 +113,9 @@ public final class InventoryBehavior extends Behavior {
if (stack.isEmpty()) {
continue;
}
if (Baritone.settings().itemSaver.value && (stack.getItemDamage() + Baritone.settings().itemSaverThreshold.value) >= stack.getMaxDamage() && stack.getMaxDamage() > 1) {
continue;
}
if (cla$$.isInstance(stack.getItem())) {
double speed = ToolSet.calculateSpeedVsBlock(stack, against.getDefaultState()); // takes into account enchants
if (speed > bestSpeed) {
@@ -149,6 +153,10 @@ public final class InventoryBehavior extends Behavior {
}
public boolean throwaway(boolean select, Predicate<? super ItemStack> desired) {
return throwaway(select, desired, Baritone.settings().allowInventory.value);
}
public boolean throwaway(boolean select, Predicate<? super ItemStack> desired, boolean allowInventory) {
EntityPlayerSP p = ctx.player();
NonNullList<ItemStack> inv = p.inventory.mainInventory;
for (int i = 0; i < 9; i++) {
@@ -181,6 +189,19 @@ public final class InventoryBehavior extends Behavior {
}
}
}
if (allowInventory) {
for (int i = 9; i < 36; i++) {
if (desired.test(inv.get(i))) {
swapWithHotBar(i, 7);
if (select) {
p.inventory.currentItem = 7;
}
return true;
}
}
}
return false;
}
}

View File

@@ -1,292 +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.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.api.utils.BetterBlockPos;
import baritone.cache.ContainerMemory;
import baritone.utils.BlockStateInterface;
import net.minecraft.block.Block;
import net.minecraft.block.BlockBed;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.network.Packet;
import net.minecraft.network.play.client.CPacketCloseWindow;
import net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock;
import net.minecraft.network.play.server.SPacketCloseWindow;
import net.minecraft.network.play.server.SPacketOpenWindow;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityLockable;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentTranslation;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
/**
* doesn't work for horse inventories :^)
*
* @author Brady
* @since 8/6/2018
*/
public final class MemoryBehavior extends Behavior {
private final List<FutureInventory> futureInventories = new ArrayList<>(); // this is per-bot
private Integer enderChestWindowId; // nae nae
public MemoryBehavior(Baritone baritone) {
super(baritone);
}
@Override
public synchronized void onTick(TickEvent event) {
if (!Baritone.settings().containerMemory.value) {
return;
}
if (event.getType() == TickEvent.Type.OUT) {
enderChestWindowId = null;
futureInventories.clear();
}
}
@Override
public synchronized void onPlayerUpdate(PlayerUpdateEvent event) {
if (event.getState() == EventState.PRE) {
updateInventory();
}
}
@Override
public synchronized void onSendPacket(PacketEvent event) {
if (!Baritone.settings().containerMemory.value) {
return;
}
Packet p = event.getPacket();
if (event.getState() == EventState.PRE) {
if (p instanceof CPacketPlayerTryUseItemOnBlock) {
CPacketPlayerTryUseItemOnBlock packet = event.cast();
TileEntity tileEntity = ctx.world().getTileEntity(packet.getPos());
// if tileEntity is an ender chest, we don't need to do anything. ender chests are treated the same regardless of what coordinate right clicked
// Ensure the TileEntity is a container of some sort
if (tileEntity instanceof TileEntityLockable) {
TileEntityLockable lockable = (TileEntityLockable) tileEntity;
int size = lockable.getSizeInventory();
BetterBlockPos position = BetterBlockPos.from(tileEntity.getPos());
BetterBlockPos adj = BetterBlockPos.from(neighboringConnectedBlock(position));
System.out.println(position + " " + adj);
if (adj != null) {
size *= 2; // double chest or double trapped chest
if (adj.getX() < position.getX() || adj.getZ() < position.getZ()) {
position = adj; // standardize on the lower coordinate, regardless of which side of the large chest we right clicked
}
}
this.futureInventories.add(new FutureInventory(System.nanoTime() / 1000000L, size, lockable.getGuiID(), position));
}
}
if (p instanceof CPacketCloseWindow) {
getCurrent().save();
}
}
}
@Override
public synchronized void onReceivePacket(PacketEvent event) {
if (!Baritone.settings().containerMemory.value) {
return;
}
Packet p = event.getPacket();
if (event.getState() == EventState.PRE) {
if (p instanceof SPacketOpenWindow) {
SPacketOpenWindow packet = event.cast();
// Remove any entries that were created over a second ago, this should make up for INSANE latency
futureInventories.removeIf(i -> System.nanoTime() / 1000000L - i.time > 1000);
System.out.println("Received packet " + packet.getGuiId() + " " + packet.getEntityId() + " " + packet.getSlotCount() + " " + packet.getWindowId());
System.out.println(packet.getWindowTitle());
if (packet.getWindowTitle() instanceof TextComponentTranslation && ((TextComponentTranslation) packet.getWindowTitle()).getKey().equals("container.enderchest")) {
// title is not customized (i.e. this isn't just a renamed shulker)
enderChestWindowId = packet.getWindowId();
return;
}
futureInventories.stream()
.filter(i -> i.type.equals(packet.getGuiId()) && i.slots == packet.getSlotCount())
.findFirst().ifPresent(matched -> {
// Remove the future inventory
futureInventories.remove(matched);
// Setup the remembered inventory
getCurrentContainer().setup(matched.pos, packet.getWindowId(), packet.getSlotCount());
});
}
if (p instanceof SPacketCloseWindow) {
getCurrent().save();
}
}
}
@Override
public void onBlockInteract(BlockInteractEvent event) {
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(ctx, event.getPos()) instanceof BlockBed) {
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, BetterBlockPos.from(event.getPos())));
}
}
@Override
public void onPlayerDeath() {
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("death", Waypoint.Tag.DEATH, ctx.playerFeet()));
}
private void updateInventory() {
if (!Baritone.settings().containerMemory.value) {
return;
}
int windowId = ctx.player().openContainer.windowId;
if (enderChestWindowId != null) {
if (windowId == enderChestWindowId) {
getCurrent().contents = ctx.player().openContainer.getInventory().subList(0, 27);
} else {
getCurrent().save();
enderChestWindowId = null;
}
}
if (getCurrentContainer() != null) {
getCurrentContainer().getInventoryFromWindow(windowId).ifPresent(inventory -> inventory.updateFromOpenWindow(ctx));
}
}
private ContainerMemory getCurrentContainer() {
if (baritone.getWorldProvider().getCurrentWorld() == null) {
return null;
}
return (ContainerMemory) baritone.getWorldProvider().getCurrentWorld().getContainerMemory();
}
private BlockPos neighboringConnectedBlock(BlockPos in) {
BlockStateInterface bsi = baritone.bsi;
Block block = bsi.get0(in).getBlock();
if (block != Blocks.TRAPPED_CHEST && block != Blocks.CHEST) {
return null; // other things that have contents, but can be placed adjacent without combining
}
for (int i = 0; i < 4; i++) {
BlockPos adj = in.offset(EnumFacing.byHorizontalIndex(i));
if (bsi.get0(adj).getBlock() == block) {
return adj;
}
}
return null;
}
/**
* An inventory that we are not yet fully aware of, but are expecting to exist at some point in the future.
*/
private static final class FutureInventory {
/**
* The time that we initially expected the inventory to be provided, in milliseconds
*/
private final long time;
/**
* The amount of slots in the inventory
*/
private final int slots;
/**
* The type of inventory
*/
private final String type;
/**
* The position of the inventory container
*/
private final BlockPos pos;
private FutureInventory(long time, int slots, String type, BlockPos pos) {
this.time = time;
this.slots = slots;
this.type = type;
this.pos = pos;
// betterblockpos has censoring
System.out.println("Future inventory created " + time + " " + slots + " " + type + " " + BetterBlockPos.from(pos));
}
}
public Optional<List<ItemStack>> echest() {
return Optional.ofNullable(getCurrent().contents).map(Collections::unmodifiableList);
}
public EnderChestMemory getCurrent() {
Path path = baritone.getWorldProvider().getCurrentWorld().directory;
return EnderChestMemory.getByServerAndPlayer(path.getParent(), ctx.player().getUniqueID());
}
public static class EnderChestMemory {
private static final Map<Path, EnderChestMemory> memory = new HashMap<>();
private final Path enderChest;
private List<ItemStack> contents;
private EnderChestMemory(Path enderChest) {
this.enderChest = enderChest;
System.out.println("Echest storing in " + enderChest);
try {
this.contents = ContainerMemory.readItemStacks(Files.readAllBytes(enderChest));
} catch (IOException e) {
e.printStackTrace();
System.out.println("CANNOT read echest =( =(");
this.contents = null;
}
}
public synchronized void save() {
System.out.println("Saving");
if (contents != null) {
try {
enderChest.getParent().toFile().mkdir();
Files.write(enderChest, ContainerMemory.writeItemStacks(contents));
} catch (IOException e) {
e.printStackTrace();
System.out.println("CANNOT save echest =( =(");
}
}
}
private static synchronized EnderChestMemory getByServerAndPlayer(Path serverStorage, UUID player) {
return memory.computeIfAbsent(serverStorage.resolve("echests").resolve(player.toString()), EnderChestMemory::new);
}
}
}

View File

@@ -52,6 +52,10 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
private Goal goal;
private CalculationContext context;
/*eta*/
private int ticksElapsedSoFar;
private BetterBlockPos startPosition;
private boolean safeToCancel;
private boolean pauseRequestedLastTick;
private boolean unpausedLastTick;
@@ -95,9 +99,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
baritone.getPathingControlManager().cancelEverything();
return;
}
expectedSegmentStart = pathStart();
baritone.getPathingControlManager().preTick();
tickPath();
ticksElapsedSoFar++;
dispatchEvents();
}
@@ -372,6 +378,40 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
return context;
}
public Optional<Double> estimatedTicksToGoal() {
BetterBlockPos currentPos = ctx.playerFeet();
if (goal == null || currentPos == null || startPosition == null) {
return Optional.empty();
}
if (goal.isInGoal(ctx.playerFeet())) {
resetEstimatedTicksToGoal();
return Optional.of(0.0);
}
if (ticksElapsedSoFar == 0) {
return Optional.empty();
}
double current = goal.heuristic(currentPos.x, currentPos.y, currentPos.z);
double start = goal.heuristic(startPosition.x, startPosition.y, startPosition.z);
if (current == start) {// can't check above because current and start can be equal even if currentPos and startPosition are not
return Optional.empty();
}
double eta = Math.abs(current - goal.heuristic()) * ticksElapsedSoFar / Math.abs(start - current);
return Optional.of(eta);
}
private void resetEstimatedTicksToGoal() {
resetEstimatedTicksToGoal(expectedSegmentStart);
}
private void resetEstimatedTicksToGoal(BlockPos start) {
resetEstimatedTicksToGoal(new BetterBlockPos(start));
}
private void resetEstimatedTicksToGoal(BetterBlockPos start) {
ticksElapsedSoFar = 0;
startPosition = start;
}
/**
* See issue #209
*
@@ -468,6 +508,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
if (executor.get().getPath().positions().contains(expectedSegmentStart)) {
queuePathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
current = executor.get();
resetEstimatedTicksToGoal(start);
} else {
logDebug("Warning: discarding orphan path segment with incorrect start");
}

View File

@@ -0,0 +1,92 @@
/*
* 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.behavior;
import baritone.Baritone;
import baritone.api.cache.IWaypoint;
import baritone.api.cache.Waypoint;
import baritone.api.event.events.BlockInteractEvent;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Helper;
import baritone.utils.BlockStateInterface;
import net.minecraft.block.BlockBed;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.event.ClickEvent;
import net.minecraft.util.text.event.HoverEvent;
import java.util.Set;
import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
public class WaypointBehavior extends Behavior {
public WaypointBehavior(Baritone baritone) {
super(baritone);
}
@Override
public void onBlockInteract(BlockInteractEvent event) {
if (!Baritone.settings().doBedWaypoints.value)
return;
if (event.getType() == BlockInteractEvent.Type.USE) {
BetterBlockPos pos = BetterBlockPos.from(event.getPos());
IBlockState state = BlockStateInterface.get(ctx, pos);
if (state.getBlock() instanceof BlockBed) {
if (state.getValue(BlockBed.PART) == BlockBed.EnumPartType.FOOT) {
pos = pos.offset(state.getValue(BlockBed.FACING));
}
Set<IWaypoint> waypoints = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getByTag(IWaypoint.Tag.BED);
boolean exists = waypoints.stream().map(IWaypoint::getLocation).filter(pos::equals).findFirst().isPresent();
if (!exists) {
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, pos));
}
}
}
}
@Override
public void onPlayerDeath() {
if (!Baritone.settings().doDeathWaypoints.value)
return;
Waypoint deathWaypoint = new Waypoint("death", Waypoint.Tag.DEATH, ctx.playerFeet());
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(deathWaypoint);
ITextComponent component = new TextComponentString("Death position saved.");
component.getStyle()
.setColor(TextFormatting.WHITE)
.setHoverEvent(new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
new TextComponentString("Click to goto death")
))
.setClickEvent(new ClickEvent(
ClickEvent.Action.RUN_COMMAND,
String.format(
"%s%s goto %s @ %d",
FORCE_COMMAND_PREFIX,
"wp",
deathWaypoint.getTag().getName(),
deathWaypoint.getCreationTimestamp()
)
));
Helper.HELPER.logDirect(component);
}
}

View File

@@ -209,7 +209,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
private BlockPos guessPosition() {
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
IWorldData data = ibaritone.getWorldProvider().getCurrentWorld();
if (data != null && data.getCachedWorld() == this) {
if (data != null && data.getCachedWorld() == this && ibaritone.getPlayerContext().player() != null) {
return ibaritone.getPlayerContext().playerFeet();
}
}

View File

@@ -123,7 +123,7 @@ public final class ChunkPacker {
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) {
if (BlockLiquid.getSlopeAngle(chunk.getWorld(), new BlockPos(x + (chunk.x << 4), y, z + (chunk.z << 4)), state.getMaterial(), state) == -1000.0F) {
return PathingBlockType.WATER;
}
return PathingBlockType.AVOID;

View File

@@ -1,183 +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.cache;
import baritone.Baritone;
import baritone.api.cache.IContainerMemory;
import baritone.api.cache.IRememberedInventory;
import baritone.api.utils.IPlayerContext;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketBuffer;
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.*;
public class ContainerMemory implements IContainerMemory {
private final Path saveTo;
/**
* The current remembered inventories
*/
private final Map<BlockPos, RememberedInventory> inventories = new HashMap<>();
public ContainerMemory(Path saveTo) {
this.saveTo = saveTo;
try {
read(Files.readAllBytes(saveTo));
} catch (NoSuchFileException ignored) {
inventories.clear();
} catch (Exception ex) {
ex.printStackTrace();
inventories.clear();
}
}
private void read(byte[] bytes) throws IOException {
PacketBuffer in = new PacketBuffer(Unpooled.wrappedBuffer(bytes));
int chests = in.readInt();
for (int i = 0; i < chests; i++) {
int x = in.readInt();
int y = in.readInt();
int z = in.readInt();
RememberedInventory rem = new RememberedInventory();
rem.items.addAll(readItemStacks(in));
rem.size = rem.items.size();
rem.windowId = -1;
if (rem.items.isEmpty()) {
continue; // this only happens if the list has no elements, not if the list has elements that are all empty item stacks
}
inventories.put(new BlockPos(x, y, z), rem);
}
}
public synchronized void save() throws IOException {
if (!Baritone.settings().containerMemory.value) {
return;
}
ByteBuf buf = Unpooled.buffer(0, Integer.MAX_VALUE);
PacketBuffer out = new PacketBuffer(buf);
out.writeInt(inventories.size());
for (Map.Entry<BlockPos, RememberedInventory> entry : inventories.entrySet()) {
out = new PacketBuffer(out.writeInt(entry.getKey().getX()));
out = new PacketBuffer(out.writeInt(entry.getKey().getY()));
out = new PacketBuffer(out.writeInt(entry.getKey().getZ()));
out = writeItemStacks(entry.getValue().getContents(), out);
}
Files.write(saveTo, out.array());
}
public synchronized void setup(BlockPos pos, int windowId, int slotCount) {
RememberedInventory inventory = inventories.computeIfAbsent(pos, x -> new RememberedInventory());
inventory.windowId = windowId;
inventory.size = slotCount;
}
public synchronized Optional<RememberedInventory> getInventoryFromWindow(int windowId) {
return inventories.values().stream().filter(i -> i.windowId == windowId).findFirst();
}
@Override
public final synchronized RememberedInventory getInventoryByPos(BlockPos pos) {
return inventories.get(pos);
}
@Override
public final synchronized Map<BlockPos, IRememberedInventory> getRememberedInventories() {
// make a copy since this map is modified from the packet thread
return new HashMap<>(inventories);
}
public static List<ItemStack> readItemStacks(byte[] bytes) throws IOException {
PacketBuffer in = new PacketBuffer(Unpooled.wrappedBuffer(bytes));
return readItemStacks(in);
}
public static List<ItemStack> readItemStacks(PacketBuffer in) throws IOException {
int count = in.readInt();
List<ItemStack> result = new ArrayList<>();
for (int i = 0; i < count; i++) {
result.add(in.readItemStack());
}
return result;
}
public static byte[] writeItemStacks(List<ItemStack> write) {
ByteBuf buf = Unpooled.buffer(0, Integer.MAX_VALUE);
PacketBuffer out = new PacketBuffer(buf);
out = writeItemStacks(write, out);
return out.array();
}
public static PacketBuffer writeItemStacks(List<ItemStack> write, PacketBuffer out2) {
PacketBuffer out = out2; // avoid reassigning an argument LOL
out = new PacketBuffer(out.writeInt(write.size()));
for (ItemStack stack : write) {
out = out.writeItemStack(stack);
}
return out;
}
/**
* An inventory that we are aware of.
* <p>
* Associated with a {@link BlockPos} in {@link ContainerMemory#inventories}.
*/
public static class RememberedInventory implements IRememberedInventory {
/**
* The list of items in the inventory
*/
private final List<ItemStack> items;
/**
* The last known window ID of the inventory
*/
private int windowId;
/**
* The size of the inventory
*/
private int size;
private RememberedInventory() {
this.items = new ArrayList<>();
}
@Override
public final List<ItemStack> getContents() {
return Collections.unmodifiableList(this.items);
}
@Override
public final int getSize() {
return this.size;
}
public void updateFromOpenWindow(IPlayerContext ctx) {
items.clear();
items.addAll(ctx.player().openContainer.getInventory().subList(0, size));
}
}
}

View File

@@ -19,7 +19,6 @@ package baritone.cache;
import baritone.Baritone;
import baritone.api.cache.ICachedWorld;
import baritone.api.cache.IContainerMemory;
import baritone.api.cache.IWaypointCollection;
import baritone.api.cache.IWorldData;
@@ -35,7 +34,6 @@ public class WorldData implements IWorldData {
public final CachedWorld cache;
private final WaypointCollection waypoints;
private final ContainerMemory containerMemory;
//public final MapData map;
public final Path directory;
public final int dimension;
@@ -44,7 +42,6 @@ public class WorldData implements IWorldData {
this.directory = directory;
this.cache = new CachedWorld(directory.resolve("cache"), dimension);
this.waypoints = new WaypointCollection(directory.resolve("waypoints"));
this.containerMemory = new ContainerMemory(directory.resolve("containers"));
this.dimension = dimension;
}
@@ -53,15 +50,6 @@ public class WorldData implements IWorldData {
System.out.println("Started saving the world in a new thread");
cache.save();
});
Baritone.getExecutor().execute(() -> {
System.out.println("Started saving saved containers in a new thread");
try {
containerMemory.save();
} catch (IOException e) {
e.printStackTrace();
System.out.println("Failed to save saved containers");
}
});
}
@Override
@@ -73,9 +61,4 @@ public class WorldData implements IWorldData {
public IWaypointCollection getWaypoints() {
return this.waypoints;
}
@Override
public IContainerMemory getContainerMemory() {
return this.containerMemory;
}
}

View File

@@ -24,6 +24,7 @@ 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.World;
import org.apache.commons.lang3.SystemUtils;
import java.io.File;
@@ -44,9 +45,11 @@ public class WorldProvider implements IWorldProvider, Helper {
private static final Map<Path, WorldData> worldCache = new HashMap<>(); // this is how the bots have the same cached world
private WorldData currentWorld;
private World mcWorld; // this let's us detect a broken load/unload hook
@Override
public final WorldData getCurrentWorld() {
detectAndHandleBrokenLoading();
return this.currentWorld;
}
@@ -77,7 +80,16 @@ public class WorldProvider implements IWorldProvider, Helper {
directory = new File(directory, "baritone");
readme = directory;
} else { // Otherwise, the server must be remote...
String folderName = mc.getCurrentServerData().serverIP;
String folderName;
if (mc.getCurrentServerData() != null) {
folderName = mc.getCurrentServerData().serverIP;
} else {
//replaymod causes null currentServerData and false singleplayer.
System.out.println("World seems to be a replay. Not loading Baritone cache.");
currentWorld = null;
mcWorld = mc.world;
return;
}
if (SystemUtils.IS_OS_WINDOWS) {
folderName = folderName.replace(":", "_");
}
@@ -103,11 +115,13 @@ public class WorldProvider implements IWorldProvider, Helper {
synchronized (worldCache) {
this.currentWorld = worldCache.computeIfAbsent(dir, d -> new WorldData(d, dimension));
}
this.mcWorld = mc.world;
}
public final void closeWorld() {
WorldData world = this.currentWorld;
this.currentWorld = null;
this.mcWorld = null;
if (world == null) {
return;
}
@@ -115,8 +129,25 @@ public class WorldProvider implements IWorldProvider, Helper {
}
public final void ifWorldLoaded(Consumer<WorldData> currentWorldConsumer) {
detectAndHandleBrokenLoading();
if (this.currentWorld != null) {
currentWorldConsumer.accept(this.currentWorld);
}
}
private final void detectAndHandleBrokenLoading() {
if (this.mcWorld != mc.world) {
if (this.currentWorld != null) {
System.out.println("mc.world unloaded unnoticed! Unloading Baritone cache now.");
closeWorld();
}
if (mc.world != null) {
System.out.println("mc.world loaded unnoticed! Loading Baritone cache now.");
initWorld(mc.world.provider.getDimensionType().getId());
}
} else if (currentWorld == null && mc.world != null && (mc.isSingleplayer() || mc.getCurrentServerData() != null)) {
System.out.println("Retrying to load Baritone cache");
initWorld(mc.world.provider.getDimensionType().getId());
}
}
}

View File

@@ -124,7 +124,7 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
}
} else if (argc.hasExactlyOne()) {
for (Settings.Setting setting : settings.allSettings) {
if (setting.getName().equals("logger")) {
if (SettingsUtil.javaOnlySetting(setting)) {
continue;
}
if (setting.getName().equalsIgnoreCase(pair.getFirst())) {
@@ -177,7 +177,7 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
.stream();
}
Settings.Setting setting = settings.byLowerName.get(argc.getString().toLowerCase(Locale.US));
if (setting != null) {
if (setting != null && !SettingsUtil.javaOnlySetting(setting)) {
if (setting.getValueClass() == Boolean.class) {
TabCompleteHelper helper = new TabCompleteHelper();
if ((Boolean) setting.value) {

View File

@@ -38,10 +38,12 @@ public final class DefaultCommands {
new GotoCommand(baritone),
new PathCommand(baritone),
new ProcCommand(baritone),
new ETACommand(baritone),
new VersionCommand(baritone),
new RepackCommand(baritone),
new BuildCommand(baritone),
new SchematicaCommand(baritone),
new LitematicaCommand(baritone),
new ComeCommand(baritone),
new AxisCommand(baritone),
new ForceCancelCommand(baritone),
@@ -50,7 +52,6 @@ public final class DefaultCommands {
new TunnelCommand(baritone),
new RenderCommand(baritone),
new FarmCommand(baritone),
new ChestsCommand(baritone),
new FollowCommand(baritone),
new ExploreFilterCommand(baritone),
new ReloadAllCommand(baritone),

View File

@@ -0,0 +1,85 @@
/*
* 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.command.defaults;
import baritone.api.IBaritone;
import baritone.api.pathing.calc.IPathingControlManager;
import baritone.api.process.IBaritoneProcess;
import baritone.api.behavior.IPathingBehavior;
import baritone.api.command.Command;
import baritone.api.command.exception.CommandException;
import baritone.api.command.exception.CommandInvalidStateException;
import baritone.api.command.argument.IArgConsumer;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
public class ETACommand extends Command {
public ETACommand(IBaritone baritone) {
super(baritone, "eta");
}
@Override
public void execute(String label, IArgConsumer args) throws CommandException {
args.requireMax(0);
IPathingControlManager pathingControlManager = baritone.getPathingControlManager();
IBaritoneProcess process = pathingControlManager.mostRecentInControl().orElse(null);
if (process == null) {
throw new CommandInvalidStateException("No process in control");
}
IPathingBehavior pathingBehavior = baritone.getPathingBehavior();
double ticksRemainingInSegment = pathingBehavior.ticksRemainingInSegment().orElse(Double.NaN);
double ticksRemainingInGoal = pathingBehavior.estimatedTicksToGoal().orElse(Double.NaN);
logDirect(String.format(
"Next segment: %.1fs (%.0f ticks)\n" +
"Goal: %.1fs (%.0f ticks)",
ticksRemainingInSegment / 20, // we just assume tps is 20, it isn't worth the effort that is needed to calculate it exactly
ticksRemainingInSegment,
ticksRemainingInGoal / 20,
ticksRemainingInGoal
));
}
@Override
public Stream<String> tabComplete(String label, IArgConsumer args) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "View the current ETA";
}
@Override
public List<String> getLongDesc() {
return Arrays.asList(
"The ETA command provides information about the estimated time until the next segment.",
"and the goal",
"",
"Be aware that the ETA to your goal is really unprecise",
"",
"Usage:",
"> eta - View ETA, if present"
);
}
}

View File

@@ -56,6 +56,7 @@ public class ExecutionControlCommands {
@Override
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
baritone.getInputOverrideHandler().clearAllKeys();
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
}
@@ -79,7 +80,7 @@ public class ExecutionControlCommands {
}
}
);
pauseCommand = new Command(baritone, "pause", "p") {
pauseCommand = new Command(baritone, "pause", "p", "paws") {
@Override
public void execute(String label, IArgConsumer args) throws CommandException {
args.requireMax(0);
@@ -112,7 +113,7 @@ public class ExecutionControlCommands {
);
}
};
resumeCommand = new Command(baritone, "resume", "r") {
resumeCommand = new Command(baritone, "resume", "r", "unpause", "unpaws") {
@Override
public void execute(String label, IArgConsumer args) throws CommandException {
args.requireMax(0);

View File

@@ -22,14 +22,23 @@ import baritone.api.command.Command;
import baritone.api.command.argument.IArgConsumer;
import baritone.api.command.datatypes.BlockById;
import baritone.api.command.exception.CommandException;
import baritone.api.command.helpers.TabCompleteHelper;
import baritone.api.utils.BetterBlockPos;
import baritone.cache.CachedChunk;
import net.minecraft.block.Block;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.event.ClickEvent;
import net.minecraft.util.text.event.HoverEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
public class FindCommand extends Command {
public FindCommand(IBaritone baritone) {
@@ -38,12 +47,13 @@ public class FindCommand extends Command {
@Override
public void execute(String label, IArgConsumer args) throws CommandException {
args.requireMin(1);
List<Block> toFind = new ArrayList<>();
while (args.hasAny()) {
toFind.add(args.getDatatypeFor(BlockById.INSTANCE));
}
BetterBlockPos origin = ctx.playerFeet();
toFind.stream()
ITextComponent[] components = toFind.stream()
.flatMap(block ->
ctx.worldData().getCachedWorld().getLocationsOf(
Block.REGISTRY.getNameForObject(block).getPath(),
@@ -54,13 +64,39 @@ public class FindCommand extends Command {
).stream()
)
.map(BetterBlockPos::new)
.map(BetterBlockPos::toString)
.forEach(this::logDirect);
.map(this::positionToComponent)
.toArray(ITextComponent[]::new);
if (components.length > 0) {
Arrays.asList(components).forEach(this::logDirect);
} else {
logDirect("No positions known, are you sure the blocks are cached?");
}
}
private ITextComponent positionToComponent(BetterBlockPos pos) {
String positionText = String.format("%s %s %s", pos.x, pos.y, pos.z);
String command = String.format("%sgoal %s", FORCE_COMMAND_PREFIX, positionText);
ITextComponent baseComponent = new TextComponentString(pos.toString());
ITextComponent hoverComponent = new TextComponentString("Click to set goal to this position");
baseComponent.getStyle()
.setColor(TextFormatting.GRAY)
.setInsertion(positionText)
.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, command))
.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hoverComponent));
return baseComponent;
}
@Override
public Stream<String> tabComplete(String label, IArgConsumer args) {
return args.tabCompleteDatatype(BlockById.INSTANCE);
public Stream<String> tabComplete(String label, IArgConsumer args) throws CommandException {
return new TabCompleteHelper()
.append(
CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.stream()
.map(Block.REGISTRY::getNameForObject)
.map(Object::toString)
)
.filterPrefixNamespaced(args.getString())
.sortAlphabetically()
.stream();
}
@Override
@@ -71,10 +107,11 @@ public class FindCommand extends Command {
@Override
public List<String> getLongDesc() {
return Arrays.asList(
"",
"The find command searches through Baritone's cache and attempts to find the location of the block.",
"Tab completion will suggest only cached blocks and uncached blocks can not be found.",
"",
"Usage:",
"> "
"> find <block> [...] - Try finding the listed blocks"
);
}
}

View File

@@ -24,6 +24,7 @@ import baritone.api.command.argument.IArgConsumer;
import baritone.api.command.datatypes.EntityClassById;
import baritone.api.command.datatypes.IDatatypeFor;
import baritone.api.command.datatypes.NearbyPlayer;
import baritone.api.command.exception.CommandErrorMessageException;
import baritone.api.command.exception.CommandException;
import baritone.api.command.helpers.TabCompleteHelper;
import net.minecraft.entity.Entity;
@@ -60,7 +61,7 @@ public class FollowCommand extends Command {
if (gotten instanceof Class) {
//noinspection unchecked
classes.add((Class<? extends Entity>) gotten);
} else {
} else if (gotten != null) {
entities.add((Entity) gotten);
}
}
@@ -73,12 +74,14 @@ public class FollowCommand extends Command {
if (group != null) {
logDirect(String.format("Following all %s", group.name().toLowerCase(Locale.US)));
} else {
logDirect("Following these types of entities:");
if (classes.isEmpty()) {
if (entities.isEmpty()) throw new NoEntitiesException();
logDirect("Following these entities:");
entities.stream()
.map(Entity::toString)
.forEach(this::logDirect);
} else {
logDirect("Following these types of entities:");
classes.stream()
.map(EntityList::getKey)
.map(Objects::requireNonNull)
@@ -155,4 +158,12 @@ public class FollowCommand extends Command {
this.datatype = datatype;
}
}
public static class NoEntitiesException extends CommandErrorMessageException {
protected NoEntitiesException() {
super("No valid entities in range!");
}
}
}

View File

@@ -18,47 +18,34 @@
package baritone.command.defaults;
import baritone.api.IBaritone;
import baritone.api.cache.IRememberedInventory;
import baritone.api.command.Command;
import baritone.api.command.argument.IArgConsumer;
import baritone.api.command.exception.CommandException;
import baritone.api.command.exception.CommandInvalidStateException;
import baritone.api.utils.BetterBlockPos;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
public class ChestsCommand extends Command {
public class LitematicaCommand extends Command {
public ChestsCommand(IBaritone baritone) {
super(baritone, "chests");
public LitematicaCommand(IBaritone baritone) {
super(baritone, "litematica");
}
@Override
public void execute(String label, IArgConsumer args) throws CommandException {
args.requireMax(0);
Set<Map.Entry<BlockPos, IRememberedInventory>> entries =
ctx.worldData().getContainerMemory().getRememberedInventories().entrySet();
if (entries.isEmpty()) {
throw new CommandInvalidStateException("No remembered inventories");
}
for (Map.Entry<BlockPos, IRememberedInventory> entry : entries) {
// betterblockpos has censoring
BetterBlockPos pos = new BetterBlockPos(entry.getKey());
IRememberedInventory inv = entry.getValue();
logDirect(pos.toString());
for (ItemStack item : inv.getContents()) {
ITextComponent component = item.getTextComponent();
component.appendText(String.format(" x %d", item.getCount()));
logDirect(component);
int schematic = 0;
if (args.hasAny()) {
args.requireMax(1);
if (args.is(Integer.class)) {
schematic = args.getAs(Integer.class) - 1;
}
}
try {
baritone.getBuilderProcess().buildOpenLitematic(schematic);
} catch (IndexOutOfBoundsException e) {
logDirect("Pleas provide a valid index.");
}
}
@Override
@@ -68,16 +55,17 @@ public class ChestsCommand extends Command {
@Override
public String getShortDesc() {
return "Display remembered inventories";
return "Builds the loaded schematic";
}
@Override
public List<String> getLongDesc() {
return Arrays.asList(
"The chests command lists remembered inventories, I guess?",
"Build a schematic currently open in Litematica.",
"",
"Usage:",
"> chests"
"> litematica",
"> litematica <#>"
);
}
}
}

View File

@@ -51,7 +51,7 @@ public class SchematicaCommand extends Command {
@Override
public List<String> getLongDesc() {
return Arrays.asList(
"Builds the schematica currently open in Schematica.",
"Builds the schematic currently open in Schematica.",
"",
"Usage:",
"> schematica"

View File

@@ -37,6 +37,9 @@ import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.BlockOptionalMeta;
import baritone.api.utils.BlockOptionalMetaLookup;
import baritone.utils.IRenderer;
import baritone.utils.BlockStateInterface;
import baritone.utils.schematic.StaticSchematic;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
@@ -53,6 +56,8 @@ public class SelCommand extends Command {
private ISelectionManager manager = baritone.getSelectionManager();
private BetterBlockPos pos1 = null;
private ISchematic clipboard = null;
private Vec3i clipboardOffset = null;
public SelCommand(IBaritone baritone) {
super(baritone, "sel", "selection", "s");
@@ -158,6 +163,56 @@ public class SelCommand extends Command {
}
baritone.getBuilderProcess().build("Fill", composite, origin);
logDirect("Filling now");
} else if (action == Action.COPY) {
BetterBlockPos playerPos = mc.getRenderViewEntity() != null ? BetterBlockPos.from(new BlockPos(mc.getRenderViewEntity())) : ctx.playerFeet();
BetterBlockPos pos = args.hasAny() ? args.getDatatypePost(RelativeBlockPos.INSTANCE, playerPos) : playerPos;
args.requireMax(0);
ISelection[] selections = manager.getSelections();
if (selections.length < 1) {
throw new CommandInvalidStateException("No selections");
}
BlockStateInterface bsi = new BlockStateInterface(ctx);
BetterBlockPos origin = selections[0].min();
CompositeSchematic composite = new CompositeSchematic(0, 0, 0);
for (ISelection selection : selections) {
BetterBlockPos min = selection.min();
origin = new BetterBlockPos(
Math.min(origin.x, min.x),
Math.min(origin.y, min.y),
Math.min(origin.z, min.z)
);
}
for (ISelection selection : selections) {
Vec3i size = selection.size();
BetterBlockPos min = selection.min();
IBlockState[][][] blockstates = new IBlockState[size.getX()][size.getZ()][size.getY()];
for (int x = 0; x < size.getX(); x++) {
for (int y = 0; y < size.getY(); y++) {
for (int z = 0; z < size.getZ(); z++) {
blockstates[x][z][y] = bsi.get0(min.x + x, min.y + y, min.z + z);
}
}
}
ISchematic schematic = new StaticSchematic(){{
states = blockstates;
x = size.getX();
y = size.getY();
z = size.getZ();
}};
composite.put(schematic, min.x - origin.x, min.y - origin.y, min.z - origin.z);
}
clipboard = composite;
clipboardOffset = origin.subtract(pos);
logDirect("Selection copied");
} else if (action == Action.PASTE) {
BetterBlockPos playerPos = mc.getRenderViewEntity() != null ? BetterBlockPos.from(new BlockPos(mc.getRenderViewEntity())) : ctx.playerFeet();
BetterBlockPos pos = args.hasAny() ? args.getDatatypePost(RelativeBlockPos.INSTANCE, playerPos) : playerPos;
args.requireMax(0);
if (clipboard == null) {
throw new CommandInvalidStateException("You need to copy a selection first");
}
baritone.getBuilderProcess().build("Fill", clipboard, pos.add(clipboardOffset));
logDirect("Building now");
} else if (action == Action.EXPAND || action == Action.CONTRACT || action == Action.SHIFT) {
args.requireExactly(3);
TransformTarget transformTarget = TransformTarget.getByName(args.getString());
@@ -252,6 +307,8 @@ public class SelCommand extends Command {
"> sel shell/shl [block] - The same as walls, but fills in a ceiling and floor too.",
"> sel cleararea/ca - Basically 'set air'.",
"> sel replace/r <blocks...> <with> - Replaces blocks with another block.",
"> sel copy/cp <x> <y> <z> - Copy the selected area relative to the specified or your position.",
"> sel paste/p <x> <y> <z> - Build the copied area relative to the specified or your position.",
"",
"> sel expand <target> <direction> <blocks> - Expand the targets.",
"> sel contract <target> <direction> <blocks> - Contract the targets.",
@@ -270,6 +327,8 @@ public class SelCommand extends Command {
CLEARAREA("cleararea", "ca"),
REPLACE("replace", "r"),
EXPAND("expand", "ex"),
COPY("copy", "cp"),
PASTE("paste", "p"),
CONTRACT("contract", "ct"),
SHIFT("shift", "sh");
private final String[] names;

View File

@@ -23,6 +23,7 @@ import baritone.api.Settings;
import baritone.api.command.Command;
import baritone.api.command.argument.IArgConsumer;
import baritone.api.command.exception.CommandException;
import baritone.api.command.exception.CommandInvalidStateException;
import baritone.api.command.exception.CommandInvalidTypeException;
import baritone.api.command.helpers.Paginator;
import baritone.api.command.helpers.TabCompleteHelper;
@@ -40,8 +41,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
import static baritone.api.utils.SettingsUtil.settingTypeToString;
import static baritone.api.utils.SettingsUtil.settingValueToString;
import static baritone.api.utils.SettingsUtil.*;
public class SetCommand extends Command {
@@ -65,7 +65,7 @@ public class SetCommand extends Command {
args.requireMax(1);
List<? extends Settings.Setting> toPaginate =
(viewModified ? SettingsUtil.modifiedSettings(Baritone.settings()) : Baritone.settings().allSettings).stream()
.filter(s -> !s.getName().equals("logger"))
.filter(s -> !javaOnlySetting(s))
.filter(s -> s.getName().toLowerCase(Locale.US).contains(search.toLowerCase(Locale.US)))
.sorted((s1, s2) -> String.CASE_INSENSITIVE_ORDER.compare(s1.getName(), s2.getName()))
.collect(Collectors.toList());
@@ -88,6 +88,7 @@ public class SetCommand extends Command {
hoverComponent.appendText(setting.getName());
hoverComponent.appendText(String.format("\nType: %s", settingTypeToString(setting)));
hoverComponent.appendText(String.format("\n\nValue:\n%s", settingValueToString(setting)));
hoverComponent.appendText(String.format("\n\nDefault Value:\n%s", settingDefaultToString(setting)));
String commandSuggestion = Baritone.settings().prefix.value + String.format("set %s ", setting.getName());
ITextComponent component = new TextComponentString(setting.getName());
component.getStyle().setColor(TextFormatting.GRAY);
@@ -128,6 +129,12 @@ public class SetCommand extends Command {
if (setting == null) {
throw new CommandInvalidTypeException(args.consumed(), "a valid setting");
}
if (javaOnlySetting(setting)) {
// ideally it would act as if the setting didn't exist
// but users will see it in Settings.java or its javadoc
// so at some point we have to tell them or they will see it as a bug
throw new CommandInvalidStateException(String.format("Setting %s can only be used via the api.", setting.getName()));
}
if (!doingSomething && !args.hasAny()) {
logDirect(String.format("Value of setting %s:", setting.getName()));
logDirect(settingValueToString(setting));
@@ -140,7 +147,8 @@ public class SetCommand extends Command {
throw new CommandInvalidTypeException(args.consumed(), "a toggleable setting", "some other setting");
}
//noinspection unchecked
((Settings.Setting<Boolean>) setting).value ^= true;
Settings.Setting<Boolean> asBoolSetting = (Settings.Setting<Boolean>) setting;
asBoolSetting.value ^= true;
logDirect(String.format(
"Toggled setting %s to %s",
setting.getName(),

View File

@@ -17,9 +17,11 @@
package baritone.command.defaults;
import baritone.Baritone;
import baritone.api.IBaritone;
import baritone.api.cache.IWaypoint;
import baritone.api.cache.Waypoint;
import baritone.api.cache.IWorldData;
import baritone.api.command.Command;
import baritone.api.command.argument.IArgConsumer;
import baritone.api.command.datatypes.ForWaypoints;
@@ -41,12 +43,15 @@ import net.minecraft.util.text.event.HoverEvent;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
public class WaypointsCommand extends Command {
private Map<IWorldData,List<IWaypoint>> deletedWaypoints = new HashMap<>();
public WaypointsCommand(IBaritone baritone) {
super(baritone, "waypoints", "waypoint", "wp");
}
@@ -125,11 +130,13 @@ public class WaypointsCommand extends Command {
);
}
} else if (action == Action.SAVE) {
IWaypoint.Tag tag = IWaypoint.Tag.getByName(args.getString());
IWaypoint.Tag tag = args.hasAny() ? IWaypoint.Tag.getByName(args.peekString()) : null;
if (tag == null) {
throw new CommandInvalidStateException(String.format("'%s' is not a tag ", args.consumedString()));
tag = IWaypoint.Tag.USER;
} else {
args.get();
}
String name = args.hasAny() ? args.getString() : "";
String name = (args.hasExactlyOne() || args.hasExactly(4)) ? args.getString() : "";
BetterBlockPos pos = args.hasAny()
? args.getDatatypePost(RelativeBlockPos.INSTANCE, ctx.playerFeet())
: ctx.playerFeet();
@@ -147,7 +154,42 @@ public class WaypointsCommand extends Command {
for (IWaypoint waypoint : waypoints) {
ForWaypoints.waypoints(this.baritone).removeWaypoint(waypoint);
}
logDirect(String.format("Cleared %d waypoints", waypoints.length));
deletedWaypoints.computeIfAbsent(baritone.getWorldProvider().getCurrentWorld(), k -> new ArrayList<>()).addAll(Arrays.<IWaypoint>asList(waypoints));
ITextComponent textComponent = new TextComponentString(String.format("Cleared %d waypoints, click to restore them", waypoints.length));
textComponent.getStyle().setClickEvent(new ClickEvent(
ClickEvent.Action.RUN_COMMAND,
String.format(
"%s%s restore @ %s",
FORCE_COMMAND_PREFIX,
label,
Stream.of(waypoints).map(wp -> Long.toString(wp.getCreationTimestamp())).collect(Collectors.joining(" "))
)
));
logDirect(textComponent);
} else if (action == Action.RESTORE) {
List<IWaypoint> waypoints = new ArrayList<>();
List<IWaypoint> deletedWaypoints = this.deletedWaypoints.getOrDefault(baritone.getWorldProvider().getCurrentWorld(), Collections.emptyList());
if (args.peekString().equals("@")) {
args.get();
// no args.requireMin(1) because if the user clears an empty tag there is nothing to restore
while (args.hasAny()) {
long timestamp = args.getAs(Long.class);
for (IWaypoint waypoint : deletedWaypoints) {
if (waypoint.getCreationTimestamp() == timestamp) {
waypoints.add(waypoint);
break;
}
}
}
} else {
args.requireExactly(1);
int size = deletedWaypoints.size();
int amount = Math.min(size, args.getAs(Integer.class));
waypoints = new ArrayList<>(deletedWaypoints.subList(size - amount, size));
}
waypoints.forEach(ForWaypoints.waypoints(this.baritone)::addWaypoint);
deletedWaypoints.removeIf(waypoints::contains);
logDirect(String.format("Restored %d waypoints", waypoints.size()));
} else {
IWaypoint[] waypoints = args.getDatatypeFor(ForWaypoints.INSTANCE);
IWaypoint waypoint = null;
@@ -216,6 +258,20 @@ public class WaypointsCommand extends Command {
waypoint.getCreationTimestamp()
)
));
ITextComponent recreateComponent = new TextComponentString("Click to show a command to recreate this waypoint");
recreateComponent.getStyle().setClickEvent(new ClickEvent(
ClickEvent.Action.SUGGEST_COMMAND,
String.format(
"%s%s save %s %s %s %s %s",
Baritone.settings().prefix.value, // This uses the normal prefix because it is run by the user.
label,
waypoint.getTag().getName(),
waypoint.getName(),
waypoint.getLocation().x,
waypoint.getLocation().y,
waypoint.getLocation().z
)
));
ITextComponent backComponent = new TextComponentString("Click to return to the waypoints list");
backComponent.getStyle().setClickEvent(new ClickEvent(
ClickEvent.Action.RUN_COMMAND,
@@ -227,10 +283,22 @@ public class WaypointsCommand extends Command {
));
logDirect(deleteComponent);
logDirect(goalComponent);
logDirect(recreateComponent);
logDirect(backComponent);
} else if (action == Action.DELETE) {
ForWaypoints.waypoints(this.baritone).removeWaypoint(waypoint);
logDirect("That waypoint has successfully been deleted");
deletedWaypoints.computeIfAbsent(baritone.getWorldProvider().getCurrentWorld(), k -> new ArrayList<>()).add(waypoint);
ITextComponent textComponent = new TextComponentString("That waypoint has successfully been deleted, click to restore it");
textComponent.getStyle().setClickEvent(new ClickEvent(
ClickEvent.Action.RUN_COMMAND,
String.format(
"%s%s restore @ %s",
FORCE_COMMAND_PREFIX,
label,
waypoint.getCreationTimestamp()
)
));
logDirect(textComponent);
} else if (action == Action.GOAL) {
Goal goal = new GoalBlock(waypoint.getLocation());
baritone.getCustomGoalProcess().setGoal(goal);
@@ -262,6 +330,8 @@ public class WaypointsCommand extends Command {
.sortAlphabetically()
.filterPrefix(args.getString())
.stream();
} else if (action == Action.RESTORE) {
return Stream.empty();
} else {
return args.tabCompleteDatatype(ForWaypoints.INSTANCE);
}
@@ -289,15 +359,19 @@ public class WaypointsCommand extends Command {
"",
"Note that the info, delete, and goal commands let you specify a waypoint by tag. If there is more than one waypoint with a certain tag, then they will let you select which waypoint you mean.",
"",
"Missing arguments for the save command use the USER tag, creating an unnamed waypoint and your current position as defaults.",
"",
"Usage:",
"> wp [l/list] - List all waypoints.",
"> wp <s/save> <tag> - Save your current position as an unnamed waypoint with the specified tag.",
"> wp <s/save> <tag> <name> - Save the waypoint with the specified name.",
"> wp <s/save> <tag> <name> <pos> - Save the waypoint with the specified name and position.",
"> wp <i/info/show> <tag> - Show info on a waypoint by tag.",
"> wp <d/delete> <tag> - Delete a waypoint by tag.",
"> wp <g/goal> <tag> - Set a goal to a waypoint by tag.",
"> wp <goto> <tag> - Set a goal to a waypoint by tag and start pathing."
"> wp <l/list> <tag> - List all waypoints by tag.",
"> wp <s/save> - Save an unnamed USER waypoint at your current position",
"> wp <s/save> [tag] [name] [pos] - Save a waypoint with the specified tag, name and position.",
"> wp <i/info/show> <tag/name> - Show info on a waypoint by tag or name.",
"> wp <d/delete> <tag/name> - Delete a waypoint by tag or name.",
"> wp <restore> <n> - Restore the last n deleted waypoints.",
"> wp <c/clear> <tag> - Delete all waypoints with the specified tag.",
"> wp <g/goal> <tag/name> - Set a goal to a waypoint by tag or name.",
"> wp <goto> <tag/name> - Set a goal to a waypoint by tag or name and start pathing."
);
}
@@ -307,6 +381,7 @@ public class WaypointsCommand extends Command {
SAVE("save", "s"),
INFO("info", "show", "i"),
DELETE("delete", "d"),
RESTORE("restore"),
GOAL("goal", "g"),
GOTO("goto");
private final String[] names;

View File

@@ -25,7 +25,6 @@ import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Helper;
import baritone.api.utils.PathCalculationResult;
import baritone.pathing.movement.CalculationContext;
import baritone.utils.NotificationHelper;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import java.util.Optional;
@@ -217,9 +216,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder, Helper {
if (logInfo) {
logDebug("Even with a cost coefficient of " + COEFFICIENTS[COEFFICIENTS.length - 1] + ", I couldn't get more than " + Math.sqrt(bestDist) + " blocks");
logDebug("No path found =(");
if (Baritone.settings().desktopNotifications.value) {
NotificationHelper.notify("No path found =(", true);
}
logNotification("No path found =(", true);
}
return Optional.empty();
}

View File

@@ -21,6 +21,7 @@ import baritone.Baritone;
import baritone.api.IBaritone;
import baritone.api.pathing.movement.ActionCosts;
import baritone.cache.WorldData;
import baritone.pathing.precompute.PrecomputedData;
import baritone.utils.BlockStateInterface;
import baritone.utils.ToolSet;
import baritone.utils.pathing.BetterWorldBorder;
@@ -29,11 +30,15 @@ import net.minecraft.block.state.IBlockState;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.Enchantments;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
import static baritone.api.pathing.movement.ActionCosts.COST_INF;
/**
@@ -55,11 +60,13 @@ public class CalculationContext {
public final boolean canSprint;
protected final double placeBlockCost; // protected because you should call the function instead
public final boolean allowBreak;
public final List<Block> allowBreakAnyway;
public final boolean allowParkour;
public final boolean allowParkourPlace;
public final boolean allowJumpAt256;
public final boolean allowParkourAscend;
public final boolean assumeWalkOnWater;
public final int frostWalker;
public final boolean allowDiagonalDescend;
public final boolean allowDiagonalAscend;
public final boolean allowDownward;
@@ -72,11 +79,14 @@ public class CalculationContext {
public final double walkOnWaterOnePenalty;
public final BetterWorldBorder worldBorder;
public final PrecomputedData precomputedData;
public CalculationContext(IBaritone baritone) {
this(baritone, false);
}
public CalculationContext(IBaritone baritone, boolean forUseOnAnotherThread) {
this.precomputedData = new PrecomputedData();
this.safeForThreadedUse = forUseOnAnotherThread;
this.baritone = baritone;
EntityPlayerSP player = baritone.getPlayerContext().player();
@@ -89,11 +99,13 @@ public class CalculationContext {
this.canSprint = Baritone.settings().allowSprint.value && player.getFoodStats().getFoodLevel() > 6;
this.placeBlockCost = Baritone.settings().blockPlacementPenalty.value;
this.allowBreak = Baritone.settings().allowBreak.value;
this.allowBreakAnyway = new ArrayList<>(Baritone.settings().allowBreakAnyway.value);
this.allowParkour = Baritone.settings().allowParkour.value;
this.allowParkourPlace = Baritone.settings().allowParkourPlace.value;
this.allowJumpAt256 = Baritone.settings().allowJumpAt256.value;
this.allowParkourAscend = Baritone.settings().allowParkourAscend.value;
this.assumeWalkOnWater = Baritone.settings().assumeWalkOnWater.value;
this.frostWalker = EnchantmentHelper.getMaxEnchantmentLevel(Enchantments.FROST_WALKER, baritone.getPlayerContext().player());
this.allowDiagonalDescend = Baritone.settings().allowDiagonalDescend.value;
this.allowDiagonalAscend = Baritone.settings().allowDiagonalAscend.value;
this.allowDownward = Baritone.settings().allowDownward.value;
@@ -143,14 +155,13 @@ public class CalculationContext {
return COST_INF;
}
if (!worldBorder.canPlaceAt(x, z)) {
// TODO perhaps MovementHelper.canPlaceAgainst could also use this?
return COST_INF;
}
return placeBlockCost;
}
public double breakCostMultiplierAt(int x, int y, int z, IBlockState current) {
if (!allowBreak) {
if (!allowBreak && !allowBreakAnyway.contains(current.getBlock())) {
return COST_INF;
}
if (isPossiblyProtected(x, y, z)) {

View File

@@ -25,11 +25,13 @@ import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.*;
import baritone.api.utils.input.Input;
import baritone.pathing.movement.MovementState.MovementTarget;
import baritone.pathing.precompute.Ternary;
import baritone.utils.BlockStateInterface;
import baritone.utils.ToolSet;
import net.minecraft.block.*;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.IBlockState;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
@@ -40,6 +42,7 @@ import net.minecraft.world.IBlockAccess;
import java.util.Optional;
import static baritone.pathing.movement.Movement.HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP;
import static baritone.pathing.precompute.Ternary.*;
/**
* Static helpers for cost calculation
@@ -49,8 +52,12 @@ import static baritone.pathing.movement.Movement.HORIZONTALS_BUT_ALSO_DOWN_____S
public interface MovementHelper extends ActionCosts, Helper {
static boolean avoidBreaking(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
if (!bsi.worldBorder.canPlaceAt(x, z)) {
return true;
}
Block b = state.getBlock();
return b == Blocks.ICE // ice becomes water, and water can mess up the path
return Baritone.settings().blocksToDisallowBreaking.value.contains(b)
|| 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
|| avoidAdjacentBreaking(bsi, x, y + 1, z, true)
@@ -73,7 +80,18 @@ public interface MovementHelper extends ActionCosts, Helper {
&& 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 block instanceof BlockLiquid;
if (block instanceof BlockLiquid) {
if (directlyAbove || Baritone.settings().strictLiquidCheck.value) {
return true;
}
int level = state.getValue(BlockLiquid.LEVEL);
if (level == 0) {
return true; // source blocks like to flow horizontally
}
// everything else will prefer flowing down
return !(bsi.get0(x, y - 1, z).getBlock() instanceof BlockLiquid); // assume everything is in a static state
}
return false;
}
static boolean canWalkThrough(IPlayerContext ctx, BetterBlockPos pos) {
@@ -84,29 +102,81 @@ public interface MovementHelper extends ActionCosts, Helper {
return canWalkThrough(bsi, x, y, z, bsi.get0(x, y, z));
}
static boolean canWalkThrough(CalculationContext context, int x, int y, int z, IBlockState state) {
return context.precomputedData.canWalkThrough(context.bsi, x, y, z, state);
}
static boolean canWalkThrough(CalculationContext context, int x, int y, int z) {
return context.precomputedData.canWalkThrough(context.bsi, x, y, z, context.get(x, y, z));
}
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
Ternary canWalkThrough = canWalkThroughBlockState(state);
if (canWalkThrough == YES) {
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 || block == Blocks.END_ROD) {
if (canWalkThrough == NO) {
return false;
}
return canWalkThroughPosition(bsi, x, y, z, state);
}
static Ternary canWalkThroughBlockState(IBlockState state) {
Block block = state.getBlock();
if (block == Blocks.AIR) {
return YES;
}
if (block == Blocks.FIRE || block == Blocks.TRIPWIRE || block == Blocks.WEB || block == Blocks.END_PORTAL || block == Blocks.COCOA || block instanceof BlockSkull || block instanceof BlockTrapDoor || block == Blocks.END_ROD) {
return NO;
}
if (Baritone.settings().blocksToAvoid.value.contains(block)) {
return false;
return NO;
}
if (block instanceof BlockDoor || block instanceof BlockFenceGate) {
// Because there's no nice method in vanilla to check if a door is openable or not, we just have to assume
// that anything that isn't an iron door isn't openable, ignoring that some doors introduced in mods can't
// be opened by just interacting.
return block != Blocks.IRON_DOOR;
// TODO this assumes that all doors in all mods are openable
if (block == Blocks.IRON_DOOR) {
return NO;
}
return YES;
}
if (block == Blocks.CARPET) {
return MAYBE;
}
if (block instanceof BlockSnow) {
// snow layers cached as the top layer of a packed chunk have no metadata, we can't make a decision based on their depth here
// it would otherwise make long distance pathing through snowy biomes impossible
return MAYBE;
}
if (block instanceof BlockLiquid) {
if (state.getValue(BlockLiquid.LEVEL) != 0) {
return NO;
} else {
return MAYBE;
}
}
if (block instanceof BlockCauldron) {
return NO;
}
try { // A dodgy catch-all at the end, for most blocks with default behaviour this will work, however where blocks are special this will error out, and we can handle it when we have this information
if (block.isPassable(null, null)) {
return YES;
} else {
return NO;
}
} catch (Throwable exception) {
System.out.println("The block " + state.getBlock().getLocalizedName() + " requires a special case due to the exception " + exception.getMessage());
return MAYBE;
}
}
static boolean canWalkThroughPosition(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
Block block = state.getBlock();
if (block == Blocks.CARPET) {
return canWalkOn(bsi, x, y - 1, z);
}
if (block instanceof BlockSnow) {
// 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
// default to true (mostly because it would otherwise make long distance pathing through snowy biomes impossible)
if (!bsi.worldContainsLoadedChunk(x, z)) {
@@ -120,13 +190,16 @@ public interface MovementHelper extends ActionCosts, Helper {
// ok, it's low enough we could walk through it, but is it supported?
return canWalkOn(bsi, x, y - 1, z);
}
if (isFlowing(x, y, z, state, bsi)) {
return false; // Don't walk through flowing liquids
}
if (block instanceof BlockLiquid) {
if (isFlowing(x, y, z, state, bsi)) {
return false;
}
// Everything after this point has to be a special case as it relies on the water not being flowing, which means a special case is needed.
if (Baritone.settings().assumeWalkOnWater.value) {
return false;
}
IBlockState up = bsi.get0(x, y + 1, z);
if (up.getBlock() instanceof BlockLiquid || up.getBlock() instanceof BlockLilyPad) {
return false;
@@ -137,6 +210,7 @@ public interface MovementHelper extends ActionCosts, Helper {
return block.isPassable(bsi.access, bsi.isPassableBlockPos.setPos(x, y, z));
}
/**
* canWalkThrough but also won't impede movement at all. so not including doors or fence gates (we'd have to right click),
* not including water, and not including ladders or vines or cobwebs (they slow us down)
@@ -278,6 +352,8 @@ public interface MovementHelper extends ActionCosts, Helper {
* Can I walk on this block without anything weird happening like me falling
* through? Includes water because we know that we automatically jump on
* water
* <p>
* If changing something in this function remember to also change it in precomputed data
*
* @param bsi Block state provider
* @param x The block's x position
@@ -287,32 +363,67 @@ public interface MovementHelper extends ActionCosts, Helper {
* @return Whether or not the specified block can be walked on
*/
static boolean canWalkOn(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
Block block = state.getBlock();
if (block == Blocks.AIR || block == Blocks.MAGMA) {
// early return for most common case (air)
// plus magma, which is a normal cube but it hurts you
Ternary canWalkOn = canWalkOnBlockState(state);
if (canWalkOn == YES) {
return true;
}
if (canWalkOn == NO) {
return false;
}
if (state.isBlockNormalCube()) {
return true;
return canWalkOnPosition(bsi, x, y, z, state);
}
static Ternary canWalkOnBlockState(IBlockState state) {
Block block = state.getBlock();
if (state.isBlockNormalCube() && block != Blocks.MAGMA) {
return YES;
}
if (block == Blocks.LADDER || (block == Blocks.VINE && Baritone.settings().allowVines.value)) { // TODO reconsider this
return true;
return YES;
}
if (block == Blocks.FARMLAND || block == Blocks.GRASS_PATH) {
return true;
return YES;
}
if (block == Blocks.ENDER_CHEST || block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST) {
return true;
return YES;
}
if (block == Blocks.GLASS || block == Blocks.STAINED_GLASS) {
return YES;
}
if (block instanceof BlockStairs) {
return YES;
}
if (isWater(block)) {
return MAYBE;
}
if (MovementHelper.isLava(block) && Baritone.settings().assumeWalkOnLava.value) {
return MAYBE;
}
if (block instanceof BlockSlab) {
if (!Baritone.settings().allowWalkOnBottomSlab.value) {
if (((BlockSlab) block).isDouble()) {
return YES;
}
if (state.getValue(BlockSlab.HALF) != BlockSlab.EnumBlockHalf.BOTTOM) {
return YES;
}
return NO;
}
return YES;
}
return NO;
}
static boolean canWalkOnPosition(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
Block block = state.getBlock();
if (isWater(block)) {
// 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
// BlockPos s that we'd just garbage collect immediately is actually noticeable. I don't even think it's a decrease in readability
Block up = bsi.get0(x, y + 1, z).getBlock();
if (up == Blocks.WATERLILY || up == Blocks.CARPET) {
return true;
}
if (isFlowing(x, y, z, state, bsi) || block == Blocks.FLOWING_WATER) {
if (MovementHelper.isFlowing(x, y, z, state, bsi) || block == Blocks.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;
}
@@ -320,22 +431,20 @@ public interface MovementHelper extends ActionCosts, Helper {
// if assumeWalkOnWater is off, we can only walk on water if there is water above it
return isWater(up) ^ Baritone.settings().assumeWalkOnWater.value;
}
if (Baritone.settings().assumeWalkOnLava.value && isLava(block) && !isFlowing(x, y, z, state, bsi)) {
if (MovementHelper.isLava(block) && !MovementHelper.isFlowing(x, y, z, state, bsi) && Baritone.settings().assumeWalkOnLava.value) { // if we get here it means that assumeWalkOnLava must be true, so put it last
return true;
}
if (block == Blocks.GLASS || block == Blocks.STAINED_GLASS) {
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 true;
}
return block instanceof BlockStairs;
return false; // If we don't recognise it then we want to just return false to be safe.
}
static boolean canWalkOn(CalculationContext context, int x, int y, int z, IBlockState state) {
return context.precomputedData.canWalkOn(context.bsi, x, y, z, state);
}
static boolean canWalkOn(CalculationContext context, int x, int y, int z) {
return canWalkOn(context, x, y, z, context.get(x, y, z));
}
static boolean canWalkOn(IPlayerContext ctx, BetterBlockPos pos, IBlockState state) {
@@ -354,6 +463,39 @@ public interface MovementHelper extends ActionCosts, Helper {
return canWalkOn(bsi, x, y, z, bsi.get0(x, y, z));
}
static boolean canUseFrostWalker(CalculationContext context, IBlockState state) {
return context.frostWalker != 0
&& (state.getBlock() == Blocks.WATER || state.getBlock() == Blocks.FLOWING_WATER)
&& ((Integer) state.getValue(BlockLiquid.LEVEL)) == 0;
}
static boolean canUseFrostWalker(IPlayerContext ctx, BlockPos pos) {
IBlockState state = BlockStateInterface.get(ctx, pos);
return EnchantmentHelper.hasFrostWalkerEnchantment(ctx.player())
&& (state.getBlock() == Blocks.WATER || state.getBlock() == Blocks.FLOWING_WATER)
&& ((Integer) state.getValue(BlockLiquid.LEVEL)) == 0;
}
/**
* If movements make us stand/walk on this block, will it have a top to walk on?
*/
static boolean mustBeSolidToWalkOn(CalculationContext context, int x, int y, int z, IBlockState state) {
Block block = state.getBlock();
if (block == Blocks.LADDER || block == Blocks.VINE) {
return false;
}
if (block instanceof BlockLiquid) {
if (context.assumeWalkOnWater) {
return false;
}
Block blockAbove = context.getBlock(x, y+1, z);
if (blockAbove instanceof BlockLiquid) {
return false;
}
}
return true;
}
static boolean canPlaceAgainst(BlockStateInterface bsi, int x, int y, int z) {
return canPlaceAgainst(bsi, x, y, z, bsi.get0(x, y, z));
}
@@ -367,6 +509,9 @@ public interface MovementHelper extends ActionCosts, Helper {
}
static boolean canPlaceAgainst(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
if (!bsi.worldBorder.canPlaceAt(x, z)) {
return false;
}
// 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
@@ -379,7 +524,7 @@ 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 (!canWalkThrough(context, x, y, z, state)) {
if (block instanceof BlockLiquid) {
return COST_INF;
}
@@ -432,7 +577,7 @@ public interface MovementHelper extends ActionCosts, Helper {
* @param ts previously calculated ToolSet
*/
static void switchToBestToolFor(IPlayerContext ctx, IBlockState b, ToolSet ts, boolean preferSilkTouch) {
if (!Baritone.settings().disableAutoTool.value && !Baritone.settings().assumeExternalAutoTool.value) {
if (Baritone.settings().autoTool.value && !Baritone.settings().assumeExternalAutoTool.value) {
ctx.player().inventory.currentItem = ts.getBestSlot(b.getBlock(), preferSilkTouch);
}
}

View File

@@ -68,7 +68,7 @@ public class MovementAscend extends Movement {
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;
if (!MovementHelper.canWalkOn(context.bsi, destX, y, destZ, toPlace)) {
if (!MovementHelper.canWalkOn(context, destX, y, destZ, toPlace)) {
additionalPlacementCost = context.costOfPlacingAt(destX, y, destZ, toPlace);
if (additionalPlacementCost >= COST_INF) {
return COST_INF;
@@ -94,7 +94,7 @@ public class MovementAscend extends Movement {
}
}
IBlockState srcUp2 = context.get(x, y + 2, z); // used lower down anyway
if (context.get(x, y + 3, z).getBlock() instanceof BlockFalling && (MovementHelper.canWalkThrough(context.bsi, x, y + 1, z) || !(srcUp2.getBlock() instanceof BlockFalling))) {//it would fall on us and possibly suffocate us
if (context.get(x, y + 3, z).getBlock() instanceof BlockFalling && (MovementHelper.canWalkThrough(context, x, y + 1, z) || !(srcUp2.getBlock() instanceof BlockFalling))) {//it would fall on us and possibly suffocate us
// HOWEVER, we assume that we're standing in the start position
// that means that src and src.up(1) are both air
// maybe they aren't now, but they will be by the time this starts

View File

@@ -43,6 +43,7 @@ import java.util.Set;
public class MovementDescend extends Movement {
private int numTicks = 0;
public boolean forceSafeMode = false;
public MovementDescend(IBaritone baritone, BetterBlockPos start, BetterBlockPos end) {
super(baritone, start, end, new BetterBlockPos[]{end.up(2), end.up(), end}, end.down());
@@ -52,6 +53,14 @@ public class MovementDescend extends Movement {
public void reset() {
super.reset();
numTicks = 0;
forceSafeMode = false;
}
/**
* Called by PathExecutor if needing safeMode can only be detected with knowledge about the next movement
*/
public void forceSafeMode() {
forceSafeMode = true;
}
@Override
@@ -101,7 +110,7 @@ public class MovementDescend extends Movement {
//C, D, etc determine the length of the fall
IBlockState below = context.get(destX, y - 2, destZ);
if (!MovementHelper.canWalkOn(context.bsi, destX, y - 2, destZ, below)) {
if (!MovementHelper.canWalkOn(context, destX, y - 2, destZ, below)) {
dynamicFallCost(context, x, y, z, destX, destZ, totalCost, below, res);
return;
}
@@ -109,6 +118,9 @@ public class MovementDescend extends Movement {
if (destDown.getBlock() == Blocks.LADDER || destDown.getBlock() == Blocks.VINE) {
return;
}
if (MovementHelper.canUseFrostWalker(context, destDown)) { // no need to check assumeWalkOnWater
return; // the water will freeze when we try to walk into it
}
// we walk half the block plus 0.3 to get to the edge, then we walk the other 0.2 while simultaneously falling (math.max because of how it's in parallel)
double walk = WALK_OFF_BLOCK_COST;
@@ -130,7 +142,7 @@ public class MovementDescend extends Movement {
// and potentially replace the water we're going to fall into
return false;
}
if (!MovementHelper.canWalkThrough(context.bsi, destX, y - 2, destZ, below)) {
if (!MovementHelper.canWalkThrough(context, destX, y - 2, destZ, below)) {
return false;
}
double costSoFar = 0;
@@ -146,7 +158,7 @@ public class MovementDescend extends Movement {
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.canWalkThrough(context.bsi, destX, newY, destZ, ontoBlock)) {
if (!MovementHelper.canWalkThrough(context, destX, newY, destZ, ontoBlock)) {
return false;
}
if (context.assumeWalkOnWater) {
@@ -155,7 +167,7 @@ public class MovementDescend extends Movement {
if (MovementHelper.isFlowing(destX, newY, destZ, ontoBlock, context.bsi)) {
return false; // TODO flowing check required here?
}
if (!MovementHelper.canWalkOn(context.bsi, destX, newY - 1, destZ)) {
if (!MovementHelper.canWalkOn(context, destX, newY - 1, destZ)) {
// we could punch right through the water into something else
return false;
}
@@ -174,10 +186,10 @@ public class MovementDescend extends Movement {
effectiveStartHeight = newY;
continue;
}
if (MovementHelper.canWalkThrough(context.bsi, destX, newY, destZ, ontoBlock)) {
if (MovementHelper.canWalkThrough(context, destX, newY, destZ, ontoBlock)) {
continue;
}
if (!MovementHelper.canWalkOn(context.bsi, destX, newY, destZ, ontoBlock)) {
if (!MovementHelper.canWalkOn(context, destX, newY, destZ, ontoBlock)) {
return false;
}
if (MovementHelper.isBottomSlab(ontoBlock)) {
@@ -248,6 +260,9 @@ public class MovementDescend extends Movement {
}
public boolean safeMode() {
if (forceSafeMode) {
return true;
}
// (dest - src) + dest is offset 1 more in the same direction
// so it's the block we'd need to worry about running into if we decide to sprint straight through this descend
BlockPos into = dest.subtract(src.down()).add(dest);

View File

@@ -60,7 +60,7 @@ public class MovementDiagonal extends Movement {
@Override
protected boolean safeToCancel(MovementState state) {
//too simple. backfill does not work after cornering with this
//return MovementHelper.canWalkOn(ctx, ctx.playerFeet().down());
//return context.precomputedData.canWalkOn(ctx, ctx.playerFeet().down());
EntityPlayerSP player = ctx.player();
double offset = 0.25;
double x = player.posX;
@@ -110,40 +110,49 @@ public class MovementDiagonal extends Movement {
}
public static void cost(CalculationContext context, int x, int y, int z, int destX, int destZ, MutableMoveResult res) {
if (!MovementHelper.canWalkThrough(context.bsi, destX, y + 1, destZ)) {
if (!MovementHelper.canWalkThrough(context, destX, y + 1, destZ)) {
return;
}
IBlockState destInto = context.get(destX, y, destZ);
IBlockState fromDown;
boolean ascend = false;
IBlockState destWalkOn;
boolean descend = false;
if (!MovementHelper.canWalkThrough(context.bsi, destX, y, destZ, destInto)) {
boolean frostWalker = false;
if (!MovementHelper.canWalkThrough(context, destX, y, destZ, destInto)) {
ascend = true;
if (!context.allowDiagonalAscend || !MovementHelper.canWalkThrough(context.bsi, x, y + 2, z) || !MovementHelper.canWalkOn(context.bsi, destX, y, destZ, destInto) || !MovementHelper.canWalkThrough(context.bsi, destX, y + 2, destZ)) {
if (!context.allowDiagonalAscend || !MovementHelper.canWalkThrough(context, x, y + 2, z) || !MovementHelper.canWalkOn(context, destX, y, destZ, destInto) || !MovementHelper.canWalkThrough(context, destX, y + 2, destZ)) {
return;
}
destWalkOn = destInto;
fromDown = context.get(x, y - 1, z);
} else {
destWalkOn = context.get(destX, y - 1, destZ);
if (!MovementHelper.canWalkOn(context.bsi, destX, y - 1, destZ, destWalkOn)) {
fromDown = context.get(x, y - 1, z);
boolean standingOnABlock = MovementHelper.mustBeSolidToWalkOn(context, x, y - 1, z, fromDown);
frostWalker = standingOnABlock && MovementHelper.canUseFrostWalker(context, destWalkOn);
if (!frostWalker && !MovementHelper.canWalkOn(context, destX, y - 1, destZ, destWalkOn)) {
descend = true;
if (!context.allowDiagonalDescend || !MovementHelper.canWalkOn(context.bsi, destX, y - 2, destZ) || !MovementHelper.canWalkThrough(context.bsi, destX, y - 1, destZ, destWalkOn)) {
if (!context.allowDiagonalDescend || !MovementHelper.canWalkOn(context, destX, y - 2, destZ) || !MovementHelper.canWalkThrough(context, destX, y - 1, destZ, destWalkOn)) {
return;
}
}
frostWalker &= !context.assumeWalkOnWater; // do this after checking for descends because jesus can't prevent the water from freezing, it just prevents us from relying on the water freezing
}
double multiplier = WALK_ONE_BLOCK_COST;
// For either possible soul sand, that affects half of our walking
if (destWalkOn.getBlock() == Blocks.SOUL_SAND) {
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
} else if (frostWalker) {
// frostwalker lets us walk on water without the penalty
} else if (destWalkOn.getBlock() == Blocks.WATER) {
multiplier += context.walkOnWaterOnePenalty * SQRT_2;
}
Block fromDown = context.get(x, y - 1, z).getBlock();
if (fromDown == Blocks.LADDER || fromDown == Blocks.VINE) {
Block fromDownBlock = fromDown.getBlock();
if (fromDownBlock == Blocks.LADDER || fromDownBlock == Blocks.VINE) {
return;
}
if (fromDown == Blocks.SOUL_SAND) {
if (fromDownBlock == Blocks.SOUL_SAND) {
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
}
Block cuttingOver1 = context.get(x, y - 1, destZ).getBlock();
@@ -169,17 +178,17 @@ public class MovementDiagonal extends Movement {
IBlockState pb0 = context.get(x, y, destZ);
IBlockState pb2 = context.get(destX, y, z);
if (ascend) {
boolean ATop = MovementHelper.canWalkThrough(context.bsi, x, y + 2, destZ);
boolean AMid = MovementHelper.canWalkThrough(context.bsi, x, y + 1, destZ);
boolean ALow = MovementHelper.canWalkThrough(context.bsi, x, y, destZ, pb0);
boolean BTop = MovementHelper.canWalkThrough(context.bsi, destX, y + 2, z);
boolean BMid = MovementHelper.canWalkThrough(context.bsi, destX, y + 1, z);
boolean BLow = MovementHelper.canWalkThrough(context.bsi, destX, y, z, pb2);
boolean ATop = MovementHelper.canWalkThrough(context, x, y + 2, destZ);
boolean AMid = MovementHelper.canWalkThrough(context, x, y + 1, destZ);
boolean ALow = MovementHelper.canWalkThrough(context, x, y, destZ, pb0);
boolean BTop = MovementHelper.canWalkThrough(context, destX, y + 2, z);
boolean BMid = MovementHelper.canWalkThrough(context, destX, y + 1, z);
boolean BLow = MovementHelper.canWalkThrough(context, destX, y, z, pb2);
if ((!(ATop && AMid && ALow) && !(BTop && BMid && BLow)) // no option
|| MovementHelper.avoidWalkingInto(pb0.getBlock()) // bad
|| MovementHelper.avoidWalkingInto(pb2.getBlock()) // bad
|| (ATop && AMid && MovementHelper.canWalkOn(context.bsi, x, y, destZ, pb0)) // we could just ascend
|| (BTop && BMid && MovementHelper.canWalkOn(context.bsi, destX, y, z, pb2)) // we could just ascend
|| (ATop && AMid && MovementHelper.canWalkOn(context, x, y, destZ, pb0)) // we could just ascend
|| (BTop && BMid && MovementHelper.canWalkOn(context, destX, y, z, pb2)) // we could just ascend
|| (!ATop && AMid && ALow) // head bonk A
|| (!BTop && BMid && BLow)) { // head bonk B
return;

View File

@@ -59,7 +59,7 @@ public class MovementDownward extends Movement {
if (!context.allowDownward) {
return COST_INF;
}
if (!MovementHelper.canWalkOn(context.bsi, x, y - 2, z)) {
if (!MovementHelper.canWalkOn(context, x, y - 2, z)) {
return COST_INF;
}
IBlockState down = context.get(x, y - 1, z);

View File

@@ -17,6 +17,7 @@
package baritone.pathing.movement.movements;
import baritone.Baritone;
import baritone.api.IBaritone;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
@@ -74,7 +75,7 @@ public class MovementParkour extends Movement {
return;
}
IBlockState adj = context.get(x + xDiff, y - 1, z + zDiff);
if (MovementHelper.canWalkOn(context.bsi, x + xDiff, y - 1, z + zDiff, adj)) { // don't parkour if we could just traverse (for now)
if (MovementHelper.canWalkOn(context, x + xDiff, y - 1, z + zDiff, adj)) { // don't parkour if we could just traverse (for now)
// second most common case -- we could just traverse not parkour
return;
}
@@ -91,9 +92,16 @@ 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)) {
return;
}
// we can't jump from (frozen) water with assumeWalkOnWater because we can't be sure it will be frozen
if (context.assumeWalkOnWater && standingOn.getBlock() instanceof BlockLiquid) {
return;
}
if (context.getBlock(x, y, z) instanceof BlockLiquid) {
return; // can't jump out of water
}
int maxJump;
if (standingOn.getBlock() == Blocks.SOUL_SAND) {
maxJump = 2; // 1 block gap
@@ -104,73 +112,91 @@ public class MovementParkour extends Movement {
maxJump = 3;
}
}
// check parkour jumps from smallest to largest for obstacles/walls and landing positions
int verifiedMaxJump = 1; // i - 1 (when i = 2)
for (int i = 2; i <= maxJump; i++) {
int destX = x + xDiff * i;
int destZ = z + zDiff * i;
// check head/feet
if (!MovementHelper.fullyPassable(context, destX, y + 1, destZ)) {
return;
break;
}
if (!MovementHelper.fullyPassable(context, destX, y + 2, destZ)) {
return;
break;
}
// check for ascend landing position
IBlockState destInto = context.bsi.get0(destX, y, destZ);
if (!MovementHelper.fullyPassable(context.bsi.access, context.bsi.isPassableBlockPos.setPos(destX, y, destZ), destInto)) {
if (i <= 3 && context.allowParkourAscend && context.canSprint && MovementHelper.canWalkOn(context.bsi, destX, y, destZ, destInto) && checkOvershootSafety(context.bsi, destX + xDiff, y + 1, destZ + zDiff)) {
if (i <= 3 && context.allowParkourAscend && context.canSprint && MovementHelper.canWalkOn(context, destX, y, destZ, destInto) && checkOvershootSafety(context.bsi, destX + xDiff, y + 1, destZ + zDiff)) {
res.x = destX;
res.y = y + 1;
res.z = destZ;
res.cost = i * SPRINT_ONE_BLOCK_COST + context.jumpPenalty;
return;
}
return;
break;
}
// check for flat landing position
IBlockState landingOn = context.bsi.get0(destX, y - 1, destZ);
// 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, destX, y - 1, destZ, landingOn)) {
// farmland needs to be canWalkOn otherwise farm can never work at all, but we want to specifically disallow ending a jump on farmland haha
// frostwalker works here because we can't jump from possibly unfrozen water
if ((landingOn.getBlock() != Blocks.FARMLAND && MovementHelper.canWalkOn(context, destX, y - 1, destZ, landingOn))
|| (Math.min(16, context.frostWalker + 2) >= i && MovementHelper.canUseFrostWalker(context, landingOn))
) {
if (checkOvershootSafety(context.bsi, destX + xDiff, y, destZ + zDiff)) {
res.x = destX;
res.y = y;
res.z = destZ;
res.cost = costFromJumpDistance(i) + context.jumpPenalty;
return;
}
return;
break;
}
if (!MovementHelper.fullyPassable(context, destX, y + 3, destZ)) {
return;
break;
}
verifiedMaxJump = i;
}
if (maxJump != 4) {
return;
}
// parkour place starts here
if (!context.allowParkourPlace) {
return;
}
// time 2 pop off with that dank skynet parkour place
int destX = x + 4 * xDiff;
int destZ = z + 4 * zDiff;
IBlockState toReplace = context.get(destX, y - 1, destZ);
double placeCost = context.costOfPlacingAt(destX, y - 1, destZ, toReplace);
if (placeCost >= COST_INF) {
return;
}
if (!MovementHelper.isReplaceable(destX, y - 1, destZ, toReplace, context.bsi)) {
return;
}
if (!checkOvershootSafety(context.bsi, destX + xDiff, y, destZ + zDiff)) {
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();
if (againstX == x + xDiff * 3 && againstZ == z + zDiff * 3) { // we can't turn around that fast
// check parkour jumps from largest to smallest for positions to place blocks
for (int i = verifiedMaxJump; i > 1; i--) {
int destX = x + i * xDiff;
int destZ = z + i * zDiff;
IBlockState toReplace = context.get(destX, y - 1, destZ);
double placeCost = context.costOfPlacingAt(destX, y - 1, destZ, toReplace);
if (placeCost >= COST_INF) {
continue;
}
if (MovementHelper.canPlaceAgainst(context.bsi, againstX, againstY, againstZ)) {
res.x = destX;
res.y = y;
res.z = destZ;
res.cost = costFromJumpDistance(4) + placeCost + context.jumpPenalty;
return;
if (!MovementHelper.isReplaceable(destX, y - 1, destZ, toReplace, context.bsi)) {
continue;
}
if (!checkOvershootSafety(context.bsi, destX + xDiff, y, destZ + zDiff)) {
continue;
}
for (int j = 0; j < 5; j++) {
int againstX = destX + HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP[j].getXOffset();
int againstY = y - 1 + HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP[j].getYOffset();
int againstZ = destZ + HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP[j].getZOffset();
if (againstX == destX - xDiff && againstZ == destZ - zDiff) { // we can't turn around that fast
continue;
}
if (MovementHelper.canPlaceAgainst(context.bsi, againstX, againstY, againstZ)) {
res.x = destX;
res.y = y;
res.z = destZ;
res.cost = costFromJumpDistance(i) + placeCost + context.jumpPenalty;
return;
}
}
}
}
@@ -250,7 +276,12 @@ public class MovementParkour extends Movement {
}
} else if (!ctx.playerFeet().equals(src)) {
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, false) == PlaceResult.READY_TO_PLACE) {
if (Baritone.settings().allowPlace.value // see PR #3775
&& ((Baritone) baritone).getInventoryBehavior().hasGenericThrowaway()
&& !MovementHelper.canWalkOn(ctx, dest.down())
&& !ctx.player().onGround
&& MovementHelper.attemptToPlaceABlock(state, baritone, dest.down(), true, false) == 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

@@ -101,6 +101,10 @@ public class MovementPillar extends Movement {
// 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
return COST_INF;
}
if ((from == Blocks.WATERLILY || from == Blocks.CARPET) && fromDown.getBlock() instanceof BlockLiquid) {
// to ascend here we'd have to break the block we are standing on
return COST_INF;
}
double hardness = MovementHelper.getMiningDurationTicks(context, x, y + 2, z, toBreak, true);
if (hardness >= COST_INF) {
return COST_INF;
@@ -120,7 +124,7 @@ public class MovementPillar extends Movement {
}
}
// this is commented because it may have had a purpose, but it's very unclear what it was. it's from the minebot era.
//if (!MovementHelper.canWalkOn(chkPos, check) || MovementHelper.canWalkThrough(chkPos, check)) {//if the block above where we want to break is not a full block, don't do it
//if (!MovementHelper.canWalkOn(context, chkPos, check) || MovementHelper.canWalkThrough(context, chkPos, check)) {//if the block above where we want to break is not a full block, don't do it
// TODO why does canWalkThrough mean this action is COST_INF?
// BlockFalling makes sense, and !canWalkOn deals with weird cases like if it were lava
// but I don't understand why canWalkThrough makes it impossible

View File

@@ -71,8 +71,11 @@ public class MovementTraverse extends Movement {
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);
if (MovementHelper.canWalkOn(context.bsi, destX, y - 1, destZ, destOn)) {//this is a walk, not a bridge
IBlockState srcDown = context.get(x, y - 1, z);
Block srcDownBlock = srcDown.getBlock();
boolean standingOnABlock = MovementHelper.mustBeSolidToWalkOn(context, x, y-1, z, srcDown);
boolean frostWalker = standingOnABlock && !context.assumeWalkOnWater && MovementHelper.canUseFrostWalker(context, destOn);
if (frostWalker || MovementHelper.canWalkOn(context, 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())) {
@@ -81,10 +84,12 @@ public class MovementTraverse extends Movement {
} else {
if (destOn.getBlock() == Blocks.SOUL_SAND) {
WC += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
} else if (frostWalker) {
// with frostwalker we can walk on water without the penalty, if we are sure we won't be using jesus
} else if (destOn.getBlock() == Blocks.WATER) {
WC += context.walkOnWaterOnePenalty;
}
if (srcDown == Blocks.SOUL_SAND) {
if (srcDownBlock == Blocks.SOUL_SAND) {
WC += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
}
}
@@ -102,13 +107,13 @@ public class MovementTraverse extends Movement {
}
return WC;
}
if (srcDown == Blocks.LADDER || srcDown == Blocks.VINE) {
if (srcDownBlock == Blocks.LADDER || srcDownBlock == Blocks.VINE) {
hardness1 *= 5;
hardness2 *= 5;
}
return WC + hardness1 + hardness2;
} else {//this is a bridge, so we need to place a block
if (srcDown == Blocks.LADDER || srcDown == Blocks.VINE) {
if (srcDownBlock == Blocks.LADDER || srcDownBlock == Blocks.VINE) {
return COST_INF;
}
if (MovementHelper.isReplaceable(destX, y - 1, destZ, destOn, context.bsi)) {
@@ -139,12 +144,16 @@ 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 (srcDownBlock == Blocks.SOUL_SAND || (srcDownBlock instanceof BlockSlab && !((BlockSlab) srcDownBlock).isDouble())) {
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 (!standingOnABlock) { // standing on water / swimming
return COST_INF; // this is obviously impossible
}
Block blockSrc = context.getBlock(x, y, z);
if ((blockSrc == Blocks.WATERLILY || blockSrc == Blocks.CARPET) && srcDownBlock instanceof BlockLiquid) {
return COST_INF; // we can stand on these but can't place against them
}
WC = WC * (SNEAK_ONE_BLOCK_COST / WALK_ONE_BLOCK_COST);//since we are sneak backplacing, we are sneaking lol
return WC + placeCost + hardness1 + hardness2;
}
@@ -226,7 +235,7 @@ public class MovementTraverse extends Movement {
}
}
boolean isTheBridgeBlockThere = MovementHelper.canWalkOn(ctx, positionToPlace) || ladder;
boolean isTheBridgeBlockThere = MovementHelper.canWalkOn(ctx, positionToPlace) || ladder || MovementHelper.canUseFrostWalker(ctx, positionToPlace);
BlockPos feet = ctx.playerFeet();
if (feet.getY() != dest.getY() && !ladder) {
logDebug("Wrong Y coordinate");

View File

@@ -73,8 +73,8 @@ public class PathExecutor implements IPathExecutor, Helper {
private HashSet<BlockPos> toPlace = new HashSet<>();
private HashSet<BlockPos> toWalkInto = new HashSet<>();
private PathingBehavior behavior;
private IPlayerContext ctx;
private final PathingBehavior behavior;
private final IPlayerContext ctx;
private boolean sprintNextTick;
@@ -350,7 +350,7 @@ public class PathExecutor implements IPathExecutor, Helper {
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.SPRINT, false);
// first and foremost, if allowSprint is off, or if we don't have enough hunger, don't try and sprint
if (!new CalculationContext(behavior.baritone).canSprint) {
if (!new CalculationContext(behavior.baritone, false).canSprint) {
return false;
}
IMovement current = path.movements().get(pathPosition);
@@ -380,6 +380,26 @@ public class PathExecutor implements IPathExecutor, Helper {
// however, descend and ascend don't request sprinting, because they don't know the context of what movement comes after it
if (current instanceof MovementDescend) {
if (pathPosition < path.length() - 2) {
// keep this out of onTick, even if that means a tick of delay before it has an effect
IMovement next = path.movements().get(pathPosition + 1);
if (MovementHelper.canUseFrostWalker(ctx, next.getDest().down())) {
// frostwalker only works if you cross the edge of the block on ground so in some cases we may not overshoot
// Since MovementDescend can't know the next movement we have to tell it
if (next instanceof MovementTraverse || next instanceof MovementParkour) {
boolean couldPlaceInstead = Baritone.settings().allowPlace.value && behavior.baritone.getInventoryBehavior().hasGenericThrowaway() && next instanceof MovementParkour; // traverse doesn't react fast enough
// this is true if the next movement does not ascend or descends and goes into the same cardinal direction (N-NE-E-SE-S-SW-W-NW) as the descend
// in that case current.getDirection() is e.g. (0, -1, 1) and next.getDirection() is e.g. (0, 0, 3) so the cross product of (0, 0, 1) and (0, 0, 3) is taken, which is (0, 0, 0) because the vectors are colinear (don't form a plane)
// since movements in exactly the opposite direction (e.g. descend (0, -1, 1) and traverse (0, 0, -1)) would also pass this check we also have to rule out that case
// we can do that by adding the directions because traverse is always 1 long like descend and parkour can't jump through current.getSrc().down()
boolean sameFlatDirection = !current.getDirection().up().add(next.getDirection()).equals(BlockPos.ORIGIN)
&& current.getDirection().up().crossProduct(next.getDirection()).equals(BlockPos.ORIGIN); // here's why you learn maths in school
if (sameFlatDirection && !couldPlaceInstead) {
((MovementDescend) current).forceSafeMode();
}
}
}
}
if (((MovementDescend) current).safeMode() && !((MovementDescend) current).skipToAscend()) {
logDebug("Sprinting would be unsafe");
return false;
@@ -397,11 +417,20 @@ public class PathExecutor implements IPathExecutor, Helper {
return true;
}
if (canSprintFromDescendInto(ctx, current, next)) {
if (next instanceof MovementDescend && pathPosition < path.length() - 3) {
IMovement next_next = path.movements().get(pathPosition + 2);
if (next_next instanceof MovementDescend && !canSprintFromDescendInto(ctx, next, next_next)) {
return false;
}
}
if (ctx.playerFeet().equals(current.getDest())) {
pathPosition++;
onChangeInPathPosition();
onTick();
}
return true;
}
//logDebug("Turning off sprinting " + movement + " " + next + " " + movement.getDirection() + " " + next.getDirection().down() + " " + next.getDirection().down().equals(movement.getDirection()));

View File

@@ -0,0 +1,92 @@
/*
* 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.pathing.precompute;
import baritone.pathing.movement.MovementHelper;
import baritone.utils.BlockStateInterface;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import static baritone.pathing.precompute.Ternary.MAYBE;
import static baritone.pathing.precompute.Ternary.YES;
public class PrecomputedData { // TODO add isFullyPassable
private final int[] data = new int[Block.BLOCK_STATE_IDS.size()];
private static final int COMPLETED_MASK = 1 << 0;
private static final int CAN_WALK_ON_MASK = 1 << 1;
private static final int CAN_WALK_ON_SPECIAL_MASK = 1 << 2;
private static final int CAN_WALK_THROUGH_MASK = 1 << 3;
private static final int CAN_WALK_THROUGH_SPECIAL_MASK = 1 << 4;
private int fillData(int id, IBlockState state) {
int blockData = 0;
Ternary canWalkOnState = MovementHelper.canWalkOnBlockState(state);
if (canWalkOnState == YES) {
blockData |= CAN_WALK_ON_MASK;
}
if (canWalkOnState == MAYBE) {
blockData |= CAN_WALK_ON_SPECIAL_MASK;
}
Ternary canWalkThroughState = MovementHelper.canWalkThroughBlockState(state);
if (canWalkThroughState == YES) {
blockData |= CAN_WALK_THROUGH_MASK;
}
if (canWalkOnState == MAYBE) {
blockData |= CAN_WALK_THROUGH_SPECIAL_MASK;
}
blockData |= COMPLETED_MASK;
data[id] = blockData; // in theory, this is thread "safe" because every thread should compute the exact same int to write?
return blockData;
}
public boolean canWalkOn(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
int id = Block.BLOCK_STATE_IDS.get(state);
int blockData = data[id];
if ((blockData & COMPLETED_MASK) == 0) { // we need to fill in the data
blockData = fillData(id, state);
}
if ((blockData & CAN_WALK_ON_SPECIAL_MASK) != 0) {
return MovementHelper.canWalkOnPosition(bsi, x, y, z, state);
} else {
return (blockData & CAN_WALK_ON_MASK) != 0;
}
}
public boolean canWalkThrough(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
int id = Block.BLOCK_STATE_IDS.get(state);
int blockData = data[id];
if ((blockData & COMPLETED_MASK) == 0) { // we need to fill in the data
blockData = fillData(id, state);
}
if ((blockData & CAN_WALK_THROUGH_SPECIAL_MASK) != 0) {
return MovementHelper.canWalkThroughPosition(bsi, x, y, z, state);
} else {
return (blockData & CAN_WALK_THROUGH_MASK) != 0;
}
}
}

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.pathing.precompute;
public enum Ternary {
YES, MAYBE, NO
}

View File

@@ -56,12 +56,12 @@ public final class BackfillProcess extends BaritoneProcessHelper {
Baritone.settings().backfill.value = false;
return false;
}
amIBreakingABlockHMMMMMMM();
for (BlockPos pos : new ArrayList<>(blocksToReplace.keySet())) {
if (ctx.world().getChunk(pos) instanceof EmptyChunk) {
if (ctx.world().getChunk(pos) instanceof EmptyChunk || ctx.world().getBlockState(pos).getBlock() != Blocks.AIR) {
blocksToReplace.remove(pos);
}
}
amIBreakingABlockHMMMMMMM();
baritone.getInputOverrideHandler().clearAllKeys();
return !toFillIn().isEmpty();
@@ -93,7 +93,7 @@ public final class BackfillProcess extends BaritoneProcessHelper {
}
private void amIBreakingABlockHMMMMMMM() {
if (!ctx.getSelectedBlock().isPresent()) {
if (!ctx.getSelectedBlock().isPresent() || !baritone.getPathingBehavior().isPathing()) {
return;
}
blocksToReplace.put(ctx.getSelectedBlock().get(), ctx.world().getBlockState(ctx.getSelectedBlock().get()));

View File

@@ -28,6 +28,7 @@ import baritone.api.process.PathingCommandType;
import baritone.api.schematic.FillSchematic;
import baritone.api.schematic.ISchematic;
import baritone.api.schematic.IStaticSchematic;
import baritone.api.schematic.SubstituteSchematic;
import baritone.api.schematic.format.ISchematicFormat;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.RayTraceUtils;
@@ -39,26 +40,34 @@ import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.utils.BaritoneProcessHelper;
import baritone.utils.BlockStateInterface;
import baritone.utils.NotificationHelper;
import baritone.utils.PathingCommandContext;
import baritone.utils.schematic.MapArtSchematic;
import baritone.utils.schematic.SchematicSystem;
import baritone.utils.schematic.SelectionSchematic;
import baritone.utils.schematic.format.defaults.LitematicaSchematic;
import baritone.utils.schematic.litematica.LitematicaHelper;
import baritone.utils.schematic.schematica.SchematicaHelper;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import net.minecraft.block.BlockAir;
import net.minecraft.block.BlockLiquid;
import net.minecraft.block.*;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Tuple;
import net.minecraft.util.math.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static baritone.api.pathing.movement.ActionCosts.COST_INF;
@@ -75,6 +84,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
private int layer;
private int numRepeats;
private List<IBlockState> approxPlaceable;
public int stopAtHeight = 0;
public BuilderProcess(Baritone baritone) {
super(baritone);
@@ -85,6 +95,10 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
this.name = name;
this.schematic = schematic;
this.realSchematic = null;
boolean buildingSelectionSchematic = schematic instanceof SelectionSchematic;
if (!Baritone.settings().buildSubstitutes.value.isEmpty()) {
this.schematic = new SubstituteSchematic(this.schematic, Baritone.settings().buildSubstitutes.value);
}
int x = origin.getX();
int y = origin.getY();
int z = origin.getZ();
@@ -100,8 +114,28 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
this.origin = new Vec3i(x, y, z);
this.paused = false;
this.layer = Baritone.settings().startAtLayer.value;
this.stopAtHeight = schematic.heightY();
if (Baritone.settings().buildOnlySelection.value && buildingSelectionSchematic) { // currently redundant but safer maybe
if (baritone.getSelectionManager().getSelections().length == 0) {
logDirect("Poor little kitten forgot to set a selection while BuildOnlySelection is true");
this.stopAtHeight = 0;
} else if (Baritone.settings().buildInLayers.value) {
OptionalInt minim = Stream.of(baritone.getSelectionManager().getSelections()).mapToInt(sel -> sel.min().y).min();
OptionalInt maxim = Stream.of(baritone.getSelectionManager().getSelections()).mapToInt(sel -> sel.max().y).max();
if (minim.isPresent() && maxim.isPresent()) {
int startAtHeight = Baritone.settings().layerOrder.value ? y + schematic.heightY() - maxim.getAsInt() : minim.getAsInt() - y;
this.stopAtHeight = (Baritone.settings().layerOrder.value ? y + schematic.heightY() - minim.getAsInt() : maxim.getAsInt() - y) + 1;
this.layer = Math.max(this.layer, startAtHeight / Baritone.settings().layerHeight.value); // startAtLayer or startAtHeight, whichever is highest
logDebug(String.format("Schematic starts at y=%s with height %s", y, schematic.heightY()));
logDebug(String.format("Selection starts at y=%s and ends at y=%s", minim.getAsInt(), maxim.getAsInt()));
logDebug(String.format("Considering relevant height %s - %s", startAtHeight, this.stopAtHeight));
}
}
}
this.numRepeats = 0;
this.observedCompleted = new LongOpenHashSet();
this.incorrectPositions = null;
}
public void resume() {
@@ -136,6 +170,11 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
parsed = new MapArtSchematic((IStaticSchematic) parsed);
}
if (Baritone.settings().buildOnlySelection.value) {
parsed = new SelectionSchematic(parsed, origin, baritone.getSelectionManager().getSelections());
}
build(name, parsed, origin);
return true;
}
@@ -146,10 +185,15 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
Optional<Tuple<IStaticSchematic, BlockPos>> schematic = SchematicaHelper.getOpenSchematic();
if (schematic.isPresent()) {
IStaticSchematic s = schematic.get().getFirst();
BlockPos origin = schematic.get().getSecond();
ISchematic schem = Baritone.settings().mapArtMode.value ? new MapArtSchematic(s) : s;
if (Baritone.settings().buildOnlySelection.value) {
schem = new SelectionSchematic(schem, origin, baritone.getSelectionManager().getSelections());
}
this.build(
schematic.get().getFirst().toString(),
Baritone.settings().mapArtMode.value ? new MapArtSchematic(s) : s,
schematic.get().getSecond()
schem,
origin
);
} else {
logDirect("No schematic currently open");
@@ -159,6 +203,33 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
}
}
/**
* Builds the with index 'i' given schematic placement.
*
* @param i index reference to the schematic placement list.
*/
@Override
public void buildOpenLitematic(int i) {
if (LitematicaHelper.isLitematicaPresent()) {
//if java.lang.NoSuchMethodError is thrown see comment in SchematicPlacementManager
if (LitematicaHelper.hasLoadedSchematic()) {
String name = LitematicaHelper.getName(i);
try {
LitematicaSchematic schematic1 = new LitematicaSchematic(CompressedStreamTools.readCompressed(Files.newInputStream(LitematicaHelper.getSchematicFile(i).toPath())), false);
Vec3i correctedOrigin = LitematicaHelper.getCorrectedOrigin(schematic1, i);
LitematicaSchematic schematic2 = LitematicaHelper.blackMagicFuckery(schematic1, i);
build(name, schematic2, correctedOrigin);
} catch (IOException e) {
logDirect("Schematic File could not be loaded.");
}
} else {
logDirect("No schematic currently loaded");
}
} else {
logDirect("Litematica is not present");
}
}
public void clearArea(BlockPos corner1, BlockPos corner2) {
BlockPos origin = new BlockPos(Math.min(corner1.getX(), corner2.getX()), Math.min(corner1.getY(), corner2.getY()), Math.min(corner1.getZ(), corner2.getZ()));
int widthX = Math.abs(corner1.getX() - corner2.getX()) + 1;
@@ -343,6 +414,13 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
@Override
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
return onTick(calcFailed, isSafeToCancel, 0);
}
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel, int recursions) {
if (recursions > 1000) { // onTick calls itself, don't crash
return new PathingCommand(null, PathingCommandType.SET_GOAL_AND_PATH);
}
approxPlaceable = approxPlaceable(36);
if (baritone.getInputOverrideHandler().isInputForcedDown(Input.CLICK_LEFT)) {
ticks = 5;
@@ -364,9 +442,9 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
// layer = realSchematic.heightY() should be everything
if (Baritone.settings().layerOrder.value) { // top to bottom
maxYInclusive = realSchematic.heightY() - 1;
minYInclusive = realSchematic.heightY() - layer;
minYInclusive = realSchematic.heightY() - layer * Baritone.settings().layerHeight.value;
} else {
maxYInclusive = layer - 1;
maxYInclusive = layer * Baritone.settings().layerHeight.value - 1;
minYInclusive = 0;
}
schematic = new ISchematic() {
@@ -380,6 +458,11 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return ISchematic.super.inSchematic(x, y, z, currentState) && y >= minYInclusive && y <= maxYInclusive && realSchematic.inSchematic(x, y, z, currentState);
}
@Override
public void reset() {
realSchematic.reset();
}
@Override
public int widthX() {
return realSchematic.widthX();
@@ -398,18 +481,18 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
}
BuilderCalculationContext bcc = new BuilderCalculationContext();
if (!recalc(bcc)) {
if (Baritone.settings().buildInLayers.value && layer < realSchematic.heightY()) {
if (Baritone.settings().buildInLayers.value && layer * Baritone.settings().layerHeight.value < stopAtHeight) {
logDirect("Starting layer " + layer);
layer++;
return onTick(calcFailed, isSafeToCancel);
return onTick(calcFailed, isSafeToCancel, recursions + 1);
}
Vec3i repeat = Baritone.settings().buildRepeat.value;
int max = Baritone.settings().buildRepeatCount.value;
numRepeats++;
if (repeat.equals(new Vec3i(0, 0, 0)) || (max != -1 && numRepeats >= max)) {
logDirect("Done building");
if (Baritone.settings().desktopNotifications.value && Baritone.settings().notificationOnBuildFinished.value) {
NotificationHelper.notify("Done building", false);
if (Baritone.settings().notificationOnBuildFinished.value) {
logNotification("Done building", false);
}
onLostControl();
return null;
@@ -417,8 +500,11 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
// build repeat time
layer = 0;
origin = new BlockPos(origin).add(repeat);
if (!Baritone.settings().buildRepeatSneaky.value) {
schematic.reset();
}
logDirect("Repeating build in vector " + repeat + ", new origin is " + origin);
return onTick(calcFailed, isSafeToCancel);
return onTick(calcFailed, isSafeToCancel, recursions + 1);
}
if (Baritone.settings().distanceTrim.value) {
trim();
@@ -485,10 +571,10 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
if (goal == null) {
goal = assemble(bcc, approxPlaceable, true); // we're far away, so assume that we have our whole inventory to recalculate placeable properly
if (goal == null) {
if (Baritone.settings().skipFailedLayers.value && Baritone.settings().buildInLayers.value && layer < realSchematic.heightY()) {
if (Baritone.settings().skipFailedLayers.value && Baritone.settings().buildInLayers.value && layer * Baritone.settings().layerHeight.value < realSchematic.heightY()) {
logDirect("Skipping layer that I cannot construct! Layer #" + layer);
layer++;
return onTick(calcFailed, isSafeToCancel);
return onTick(calcFailed, isSafeToCancel, recursions + 1);
}
logDirect("Unable to do it. Pausing. resume to resume, cancel to cancel");
paused = true;
@@ -573,7 +659,8 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
continue;
}
// this is not in render distance
if (!observedCompleted.contains(BetterBlockPos.longHash(blockX, blockY, blockZ))) {
if (!observedCompleted.contains(BetterBlockPos.longHash(blockX, blockY, blockZ))
&& !Baritone.settings().buildSkipBlocks.value.contains(schematic.desiredState(x, y, z, current, this.approxPlaceable).getBlock())) {
// and we've never seen this position be correct
// therefore mark as incorrect
incorrectPositions.add(new BetterBlockPos(blockX, blockY, blockZ));
@@ -802,6 +889,34 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return result;
}
public static final Set<IProperty<?>> orientationProps =
ImmutableSet.of(BlockRotatedPillar.AXIS, BlockLog.LOG_AXIS, BlockHorizontal.FACING,
BlockStairs.FACING, BlockStairs.HALF, BlockStairs.SHAPE,
BlockPane.NORTH, BlockPane.EAST, BlockPane.SOUTH, BlockPane.WEST, BlockVine.UP,
BlockTrapDoor.OPEN, BlockTrapDoor.HALF
);
private boolean sameBlockstate(IBlockState first, IBlockState second) {
if (first.getBlock() != second.getBlock()) {
return false;
}
boolean ignoreDirection = Baritone.settings().buildIgnoreDirection.value;
List<String> ignoredProps = Baritone.settings().buildIgnoreProperties.value;
if (!ignoreDirection && ignoredProps.isEmpty()) {
return first.equals(second); // early return if no properties are being ignored
}
ImmutableMap<IProperty<?>, Comparable<?>> map1 = first.getProperties();
ImmutableMap<IProperty<?>, Comparable<?>> map2 = second.getProperties();
for (IProperty<?> prop : map1.keySet()) {
if (map1.get(prop) != map2.get(prop)
&& !(ignoreDirection && orientationProps.contains(prop))
&& !ignoredProps.contains(prop.getName())) {
return false;
}
}
return true;
}
private boolean valid(IBlockState current, IBlockState desired, boolean itemVerify) {
if (desired == null) {
return true;
@@ -818,7 +933,16 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
if (!(current.getBlock() instanceof BlockAir) && Baritone.settings().buildIgnoreExisting.value && !itemVerify) {
return true;
}
return current.equals(desired);
if (Baritone.settings().buildSkipBlocks.value.contains(desired.getBlock()) && !itemVerify) {
return true;
}
if (Baritone.settings().buildValidSubstitutes.value.getOrDefault(desired.getBlock(), Collections.emptyList()).contains(current.getBlock()) && !itemVerify) {
return true;
}
if (current.equals(desired)) {
return true;
}
return sameBlockstate(current, desired);
}
public class BuilderCalculationContext extends CalculationContext {
@@ -855,7 +979,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return COST_INF;
}
IBlockState sch = getSchematic(x, y, z, current);
if (sch != null) {
if (sch != null && !Baritone.settings().buildSkipBlocks.value.contains(sch.getBlock())) {
// TODO this can return true even when allowPlace is off.... is that an issue?
if (sch.getBlock() == Blocks.AIR) {
// we want this to be air, but they're asking if they can place here
@@ -885,11 +1009,11 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
@Override
public double breakCostMultiplierAt(int x, int y, int z, IBlockState current) {
if (!allowBreak || isPossiblyProtected(x, y, z)) {
if ((!allowBreak && !allowBreakAnyway.contains(current.getBlock())) || isPossiblyProtected(x, y, z)) {
return COST_INF;
}
IBlockState sch = getSchematic(x, y, z, current);
if (sch != null) {
if (sch != null && !Baritone.settings().buildSkipBlocks.value.contains(sch.getBlock())) {
if (sch.getBlock() == Blocks.AIR) {
// it should be air
// regardless of current contents, we can break it

View File

@@ -23,7 +23,6 @@ import baritone.api.process.ICustomGoalProcess;
import baritone.api.process.PathingCommand;
import baritone.api.process.PathingCommandType;
import baritone.utils.BaritoneProcessHelper;
import baritone.utils.NotificationHelper;
/**
* As set by ExampleBaritoneControl or something idk
@@ -94,8 +93,8 @@ public final class CustomGoalProcess extends BaritoneProcessHelper implements IC
if (Baritone.settings().disconnectOnArrival.value) {
ctx.world().sendQuittingDisconnectingPacket();
}
if (Baritone.settings().desktopNotifications.value && Baritone.settings().notificationOnPathComplete.value) {
NotificationHelper.notify("Pathing complete", false);
if (Baritone.settings().notificationOnPathComplete.value) {
logNotification("Pathing complete", false);
}
return new PathingCommand(this.goal, PathingCommandType.CANCEL_AND_SET_GOAL);
}

View File

@@ -29,7 +29,6 @@ import baritone.api.process.PathingCommandType;
import baritone.api.utils.MyChunkPos;
import baritone.cache.CachedWorld;
import baritone.utils.BaritoneProcessHelper;
import baritone.utils.NotificationHelper;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
@@ -84,8 +83,8 @@ public final class ExploreProcess extends BaritoneProcessHelper implements IExpl
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
if (calcFailed) {
logDirect("Failed");
if (Baritone.settings().desktopNotifications.value && Baritone.settings().notificationOnExploreFinished.value) {
NotificationHelper.notify("Exploration failed", true);
if (Baritone.settings().notificationOnExploreFinished.value) {
logNotification("Exploration failed", true);
}
onLostControl();
return null;
@@ -93,8 +92,8 @@ public final class ExploreProcess extends BaritoneProcessHelper implements IExpl
IChunkFilter filter = calcFilter();
if (!Baritone.settings().disableCompletionCheck.value && filter.countRemain() == 0) {
logDirect("Explored all chunks");
if (Baritone.settings().desktopNotifications.value && Baritone.settings().notificationOnExploreFinished.value) {
NotificationHelper.notify("Explored all chunks", false);
if (Baritone.settings().notificationOnExploreFinished.value) {
logNotification("Explored all chunks", false);
}
onLostControl();
return null;

View File

@@ -31,7 +31,6 @@ import baritone.api.utils.input.Input;
import baritone.cache.WorldScanner;
import baritone.pathing.movement.MovementHelper;
import baritone.utils.BaritoneProcessHelper;
import baritone.utils.NotificationHelper;
import net.minecraft.block.*;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
@@ -272,8 +271,8 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro
if (calcFailed) {
logDirect("Farm failed");
if (Baritone.settings().desktopNotifications.value && Baritone.settings().notificationOnFarmFail.value) {
NotificationHelper.notify("Farm failed", true);
if (Baritone.settings().notificationOnFarmFail.value) {
logNotification("Farm failed", true);
}
onLostControl();
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);

View File

@@ -30,6 +30,7 @@ import baritone.api.utils.input.Input;
import baritone.pathing.movement.CalculationContext;
import baritone.utils.BaritoneProcessHelper;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.inventory.ContainerPlayer;
import net.minecraft.util.math.BlockPos;
@@ -57,7 +58,7 @@ public final class GetToBlockProcess extends BaritoneProcessHelper implements IG
start = ctx.playerFeet();
blacklist = new ArrayList<>();
arrivalTickCount = 0;
rescan(new ArrayList<>(), new CalculationContext(baritone));
rescan(new ArrayList<>(), new GetToBlockCalculationContext(false));
}
@Override
@@ -68,7 +69,7 @@ public final class GetToBlockProcess extends BaritoneProcessHelper implements IG
@Override
public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
if (knownLocations == null) {
rescan(new ArrayList<>(), new CalculationContext(baritone));
rescan(new ArrayList<>(), new GetToBlockCalculationContext(false));
}
if (knownLocations.isEmpty()) {
if (Baritone.settings().exploreForBlocks.value && !calcFailed) {
@@ -77,6 +78,11 @@ public final class GetToBlockProcess extends BaritoneProcessHelper implements IG
public boolean isInGoal(int x, int y, int z) {
return false;
}
@Override
public double heuristic() {
return Double.NEGATIVE_INFINITY;
}
}, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH);
}
logDirect("No known locations of " + gettingTo + ", canceling GetToBlock");
@@ -102,7 +108,7 @@ public final class GetToBlockProcess extends BaritoneProcessHelper implements IG
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.value;
if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain
List<BlockPos> current = new ArrayList<>(knownLocations);
CalculationContext context = new CalculationContext(baritone, true);
CalculationContext context = new GetToBlockCalculationContext(true);
Baritone.getExecutor().execute(() -> rescan(current, context));
}
if (goal.isInGoal(ctx.playerFeet()) && goal.isInGoal(baritone.getPathingBehavior().pathStart()) && isSafeToCancel) {
@@ -147,6 +153,20 @@ public final class GetToBlockProcess extends BaritoneProcessHelper implements IG
return !newBlacklist.isEmpty();
}
// this is to signal to MineProcess that we don't care about the allowBreak setting
// it is NOT to be used to actually calculate a path
public class GetToBlockCalculationContext extends CalculationContext {
public GetToBlockCalculationContext(boolean forUseOnAnotherThread) {
super(GetToBlockProcess.super.baritone, forUseOnAnotherThread);
}
@Override
public double breakCostMultiplierAt(int x, int y, int z, IBlockState current) {
return 1;
}
}
// safer than direct double comparison from distanceSq
private boolean areAdjacent(BlockPos posA, BlockPos posB) {
int diffX = Math.abs(posA.getX() - posB.getX());
@@ -222,7 +242,7 @@ public final class GetToBlockProcess extends BaritoneProcessHelper implements IG
if (!Baritone.settings().rightClickContainerOnArrival.value) {
return false;
}
return block == Blocks.CRAFTING_TABLE || block == Blocks.FURNACE || block == Blocks.ENDER_CHEST || block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST;
return block == Blocks.CRAFTING_TABLE || block == Blocks.FURNACE || block == Blocks.LIT_FURNACE || block == Blocks.ENDER_CHEST || block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST;
}
private boolean blockOnTopMustBeRemoved(Block block) {

View File

@@ -28,9 +28,9 @@ import baritone.cache.CachedChunk;
import baritone.cache.WorldScanner;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.precompute.PrecomputedData;
import baritone.utils.BaritoneProcessHelper;
import baritone.utils.BlockStateInterface;
import baritone.utils.NotificationHelper;
import net.minecraft.block.Block;
import net.minecraft.block.BlockAir;
import net.minecraft.block.BlockFalling;
@@ -89,25 +89,21 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
if (calcFailed) {
if (!knownOreLocations.isEmpty() && Baritone.settings().blacklistClosestOnFailure.value) {
logDirect("Unable to find any path to " + filter + ", blacklisting presumably unreachable closest instance...");
if (Baritone.settings().desktopNotifications.value && Baritone.settings().notificationOnMineFail.value) {
NotificationHelper.notify("Unable to find any path to " + filter + ", blacklisting presumably unreachable closest instance...", true);
if (Baritone.settings().notificationOnMineFail.value) {
logNotification("Unable to find any path to " + filter + ", blacklisting presumably unreachable closest instance...", true);
}
knownOreLocations.stream().min(Comparator.comparingDouble(ctx.player()::getDistanceSq)).ifPresent(blacklist::add);
knownOreLocations.removeIf(blacklist::contains);
} else {
logDirect("Unable to find any path to " + filter + ", canceling mine");
if (Baritone.settings().desktopNotifications.value && Baritone.settings().notificationOnMineFail.value) {
NotificationHelper.notify("Unable to find any path to " + filter + ", canceling mine", true);
if (Baritone.settings().notificationOnMineFail.value) {
logNotification("Unable to find any path to " + filter + ", canceling mine", true);
}
cancel();
return null;
}
}
if (!Baritone.settings().allowBreak.value) {
logDirect("Unable to mine when allowBreak is false!");
cancel();
return null;
}
updateLoucaSystem();
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.value;
List<BlockPos> curr = new ArrayList<>(knownOreLocations);
@@ -116,7 +112,10 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
Baritone.getExecutor().execute(() -> rescan(curr, context));
}
if (Baritone.settings().legitMine.value) {
addNearby();
if (!addNearby()) {
cancel();
return null;
}
}
Optional<BlockPos> shaft = curr.stream()
.filter(pos -> pos.getX() == ctx.playerFeet().getX() && pos.getZ() == ctx.playerFeet().getZ())
@@ -177,6 +176,11 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
}
private PathingCommand updateGoal() {
BlockOptionalMetaLookup filter = filterFilter();
if (filter == null) {
return null;
}
boolean legit = Baritone.settings().legitMine.value;
List<BlockPos> locs = knownOreLocations;
if (!locs.isEmpty()) {
@@ -188,10 +192,10 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
return new PathingCommand(goal, legit ? PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH : PathingCommandType.REVALIDATE_GOAL_AND_PATH);
}
// we don't know any ore locations at the moment
if (!legit) {
if (!legit && !Baritone.settings().exploreForBlocks.value) {
return null;
}
// only in non-Xray mode (aka legit mode) do we do this
// only when we should explore for blocks or are in legit mode we do this
int y = Baritone.settings().legitMineYLevel.value;
if (branchPoint == null) {
/*if (!baritone.getPathingBehavior().isPathing() && playerFeet().y == y) {
@@ -211,12 +215,17 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
public boolean isInGoal(int x, int y, int z) {
return false;
}
@Override
public double heuristic() {
return Double.NEGATIVE_INFINITY;
}
};
}
return new PathingCommand(branchPointRunaway, PathingCommandType.REVALIDATE_GOAL_AND_PATH);
}
private void rescan(List<BlockPos> already, CalculationContext context) {
BlockOptionalMetaLookup filter = filterFilter();
if (filter == null) {
return;
}
@@ -226,10 +235,10 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
List<BlockPos> dropped = droppedItemsScan();
List<BlockPos> locs = searchWorld(context, filter, ORE_LOCATIONS_COUNT, already, blacklist, dropped);
locs.addAll(dropped);
if (locs.isEmpty()) {
if (locs.isEmpty() && !Baritone.settings().exploreForBlocks.value) {
logDirect("No locations for " + filter + " known, cancelling");
if (Baritone.settings().desktopNotifications.value && Baritone.settings().notificationOnMineFail.value) {
NotificationHelper.notify("No locations for " + filter + " known, cancelling", true);
if (Baritone.settings().notificationOnMineFail.value) {
logNotification("No locations for " + filter + " known, cancelling", true);
}
cancel();
return;
@@ -366,11 +375,18 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
return prune(ctx, locs, filter, max, blacklist, dropped);
}
private void addNearby() {
private boolean addNearby() {
List<BlockPos> dropped = droppedItemsScan();
knownOreLocations.addAll(dropped);
BlockPos playerFeet = ctx.playerFeet();
BlockStateInterface bsi = new BlockStateInterface(ctx);
BlockOptionalMetaLookup filter = filterFilter();
if (filter == null) {
return false;
}
int searchDist = 10;
double fakedBlockReachDistance = 20; // at least 10 * sqrt(3) with some extra space to account for positioning within the block
for (int x = playerFeet.getX() - searchDist; x <= playerFeet.getX() + searchDist; x++) {
@@ -388,6 +404,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
}
}
knownOreLocations = prune(new CalculationContext(baritone), knownOreLocations, filter, ORE_LOCATIONS_COUNT, blacklist, dropped);
return true;
}
private static List<BlockPos> prune(CalculationContext ctx, List<BlockPos> locs2, BlockOptionalMetaLookup filter, int max, List<BlockPos> blacklist, List<BlockPos> dropped) {
@@ -463,10 +480,8 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
@Override
public void mine(int quantity, BlockOptionalMetaLookup filter) {
this.filter = filter;
if (filter != null && !Baritone.settings().allowBreak.value) {
logDirect("Unable to mine when allowBreak is false!");
this.mine(quantity, (BlockOptionalMetaLookup) null);
return;
if (this.filterFilter() == null) {
this.filter = null;
}
this.desiredQuantity = quantity;
this.knownOreLocations = new ArrayList<>();
@@ -478,4 +493,22 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
rescan(new ArrayList<>(), new CalculationContext(baritone));
}
}
private BlockOptionalMetaLookup filterFilter() {
if (this.filter == null) {
return null;
}
if (!Baritone.settings().allowBreak.value) {
BlockOptionalMetaLookup f = new BlockOptionalMetaLookup(this.filter.blocks()
.stream()
.filter(e -> Baritone.settings().allowBreakAnyway.value.contains(e.getBlock()))
.toArray(BlockOptionalMeta[]::new));
if (f.blocks().isEmpty()) {
logDirect("Unable to mine when allowBreak is false and target block is not in allowBreakAnyway!");
return null;
}
return f;
}
return filter;
}
}

View File

@@ -22,6 +22,7 @@ import baritone.api.utils.IPlayerContext;
import baritone.cache.CachedRegion;
import baritone.cache.WorldData;
import baritone.utils.accessor.IChunkProviderClient;
import baritone.utils.pathing.BetterWorldBorder;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.minecraft.block.Block;
@@ -46,6 +47,7 @@ public class BlockStateInterface {
protected final IBlockAccess world;
public final BlockPos.MutableBlockPos isPassableBlockPos;
public final IBlockAccess access;
public final BetterWorldBorder worldBorder;
private Chunk prev = null;
private CachedRegion prevCached = null;
@@ -64,6 +66,7 @@ public class BlockStateInterface {
public BlockStateInterface(World world, WorldData worldData, boolean copyLoadedChunks) {
this.world = world;
this.worldBorder = new BetterWorldBorder(world.getWorldBorder());
this.worldData = worldData;
Long2ObjectMap<Chunk> worldLoaded = ((IChunkProviderClient) world.getChunkProvider()).loadedChunks();
if (copyLoadedChunks) {

View File

@@ -207,8 +207,14 @@ public final class PathRenderer implements IRenderer {
double minX, maxX;
double minZ, maxZ;
double minY, maxY;
double y1, y2;
double y = MathHelper.cos((float) (((float) ((System.nanoTime() / 100000L) % 20000L)) / 20000F * Math.PI * 2));
double y, y1, y2;
if (!settings.renderGoalAnimated.value) {
// y = 1 causes rendering issues when the player is at the same y as the top of a block for some reason
y = 0.999F;
}
else {
y = MathHelper.cos((float) (((float) ((System.nanoTime() / 100000L) % 20000L)) / 20000F * Math.PI * 2));
}
if (goal instanceof IGoalRenderPos) {
BlockPos goalPos = ((IGoalRenderPos) goal).getGoalPos();
minX = goalPos.getX() + 0.002 - renderPosX;
@@ -243,9 +249,9 @@ public final class PathRenderer implements IRenderer {
goalPos.getX() - renderPosX,
-renderPosY,
goalPos.getZ() - renderPosZ,
partialTicks,
settings.renderGoalAnimated.value ? partialTicks : 0,
1.0,
player.world.getTotalWorldTime(),
settings.renderGoalAnimated.value ? player.world.getTotalWorldTime() : 0,
0,
256,
color.getColorComponents(null)

View File

@@ -18,6 +18,7 @@
package baritone.utils;
import baritone.Baritone;
import baritone.utils.accessor.IItemTool;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.entity.EntityPlayerSP;
@@ -26,6 +27,7 @@ import net.minecraft.init.Enchantments;
import net.minecraft.init.MobEffects;
import net.minecraft.item.Item.ToolMaterial;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemSword;
import net.minecraft.item.ItemTool;
import java.util.HashMap;
@@ -77,15 +79,16 @@ public class ToolSet {
/**
* Evaluate the material cost of a possible tool. The priority matches the
* listed order in the Item.ToolMaterial enum.
* harvest level order; there is a chance for multiple at the same with modded tools
* but in that case we don't really care.
*
* @param itemStack a possibly empty ItemStack
* @return values range from -1 to 4
* @return values from 0 up
*/
private int getMaterialCost(ItemStack itemStack) {
if (itemStack.getItem() instanceof ItemTool) {
ItemTool tool = (ItemTool) itemStack.getItem();
return ToolMaterial.valueOf(tool.getToolMaterialName()).ordinal();
return ((IItemTool) tool).getHarvestLevel();
} else {
return -1;
}
@@ -113,7 +116,7 @@ public class ToolSet {
If we actually want know what efficiency our held item has instead of the best one
possible, this lets us make pathing depend on the actual tool to be used (if auto tool is disabled)
*/
if (Baritone.settings().disableAutoTool.value && pathingCalculation) {
if (!Baritone.settings().autoTool.value && pathingCalculation) {
return player.inventory.currentItem;
}
@@ -124,6 +127,13 @@ public class ToolSet {
IBlockState blockState = b.getDefaultState();
for (int i = 0; i < 9; i++) {
ItemStack itemStack = player.inventory.getStackInSlot(i);
if (!Baritone.settings().useSwordToMine.value && itemStack.getItem() instanceof ItemSword) {
continue;
}
if (Baritone.settings().itemSaver.value && (itemStack.getItemDamage() + Baritone.settings().itemSaverThreshold.value) >= itemStack.getMaxDamage() && itemStack.getMaxDamage() > 1) {
continue;
}
double speed = calculateSpeedVsBlock(itemStack, blockState);
boolean silkTouch = hasSilkTouch(itemStack);
if (speed > highestSpeed) {
@@ -157,7 +167,7 @@ public class ToolSet {
}
private double avoidanceMultiplier(Block b) {
return Baritone.settings().blocksToAvoidBreaking.value.contains(b) ? 0.1 : 1;
return Baritone.settings().blocksToAvoidBreaking.value.contains(b) ? Baritone.settings().avoidBreakingMultiplier.value : 1;
}
/**

View File

@@ -0,0 +1,24 @@
/*
* 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.utils.accessor;
public interface IItemTool {
int getHarvestLevel();
}

View File

@@ -15,25 +15,13 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.cache;
import net.minecraft.item.ItemStack;
import java.util.List;
package baritone.utils.accessor;
/**
* @author Brady
* @since 9/23/2018
* @author rycbar
* @since 26.09.2022
*/
public interface IRememberedInventory {
public interface INBTTagLongArray {
/**
* @return The contents of this inventory
*/
List<ItemStack> getContents();
/**
* @return The number of slots in this inventory
*/
int getSize();
}
long[] getLongArray();
}

View File

@@ -0,0 +1,53 @@
/*
* 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.utils.schematic;
import baritone.api.schematic.ISchematic;
import baritone.api.schematic.MaskSchematic;
import baritone.api.selection.ISelection;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.Vec3i;
import java.util.stream.Stream;
public class SelectionSchematic extends MaskSchematic {
private final ISelection[] selections;
public SelectionSchematic(ISchematic schematic, Vec3i origin, ISelection[] selections) {
super(schematic);
this.selections = Stream.of(selections).map(
sel -> sel
.shift(EnumFacing.WEST, origin.getX())
.shift(EnumFacing.DOWN, origin.getY())
.shift(EnumFacing.NORTH, origin.getZ()))
.toArray(ISelection[]::new);
}
@Override
protected boolean partOfMask(int x, int y, int z, IBlockState currentState) {
for (ISelection selection : selections) {
if (x >= selection.min().x && y >= selection.min().y && z >= selection.min().z
&& x <= selection.max().x && y <= selection.max().y && z <= selection.max().z) {
return true;
}
}
return false;
}
}

View File

@@ -19,6 +19,7 @@ package baritone.utils.schematic.format;
import baritone.api.schematic.IStaticSchematic;
import baritone.api.schematic.format.ISchematicFormat;
import baritone.utils.schematic.format.defaults.LitematicaSchematic;
import baritone.utils.schematic.format.defaults.MCEditSchematic;
import baritone.utils.schematic.format.defaults.SpongeSchematic;
import net.minecraft.nbt.CompressedStreamTools;
@@ -65,6 +66,26 @@ public enum DefaultSchematicFormats implements ISchematicFormat {
throw new UnsupportedOperationException("Unsupported Version of a Sponge Schematic");
}
}
},
/**
* The Litematica schematic specification. Commonly denoted by the ".litematic" file extension.
*/
LITEMATICA("litematic") {
@Override
public IStaticSchematic parse(InputStream input) throws IOException {
NBTTagCompound nbt = CompressedStreamTools.readCompressed(input);
int version = nbt.getInteger("Version");
switch (version) {
case 4: //1.12
return new LitematicaSchematic(nbt, false);
case 5: //1.13-1.17
case 6: //1.18+
throw new UnsupportedOperationException("This litematic Verion is too new.");
default:
throw new UnsupportedOperationException("Unsuported Version of a Litematica Schematic");
}
}
};
private final String extension;

View File

@@ -0,0 +1,347 @@
/*
* 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.utils.schematic.format.defaults;
import baritone.utils.accessor.INBTTagLongArray;
import baritone.utils.schematic.StaticSchematic;
import net.minecraft.block.Block;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.IBlockState;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3i;
import org.apache.commons.lang3.Validate;
import javax.annotation.Nullable;
import java.util.Optional;
/**
* Based on EmersonDove's work
* <a href="https://github.com/cabaletta/baritone/pull/2544">...</a>
*
* @author rycbar
* @since 22.09.2022
*/
public final class LitematicaSchematic extends StaticSchematic {
private final Vec3i offsetMinCorner;
private final NBTTagCompound nbt;
/**
* @param nbtTagCompound a decompressed file stream aka nbt data.
* @param rotated if the schematic is rotated by 90°.
*/
public LitematicaSchematic(NBTTagCompound nbtTagCompound, boolean rotated) {
this.nbt = nbtTagCompound;
this.offsetMinCorner = new Vec3i(getMinOfSchematic("x"), getMinOfSchematic("y"), getMinOfSchematic("z"));
this.y = Math.abs(nbt.getCompoundTag("Metadata").getCompoundTag("EnclosingSize").getInteger("y"));
if (rotated) {
this.x = Math.abs(nbt.getCompoundTag("Metadata").getCompoundTag("EnclosingSize").getInteger("z"));
this.z = Math.abs(nbt.getCompoundTag("Metadata").getCompoundTag("EnclosingSize").getInteger("x"));
} else {
this.x = Math.abs(nbt.getCompoundTag("Metadata").getCompoundTag("EnclosingSize").getInteger("x"));
this.z = Math.abs(nbt.getCompoundTag("Metadata").getCompoundTag("EnclosingSize").getInteger("z"));
}
this.states = new IBlockState[this.x][this.z][this.y];
fillInSchematic();
}
/**
* @return Array of subregion names.
*/
private static String[] getRegions(NBTTagCompound nbt) {
return nbt.getCompoundTag("Regions").getKeySet().toArray(new String[0]);
}
/**
* Gets both ends from a region box for a given axis and returns the lower one.
*
* @param s axis that should be read.
* @return the lower coord of the requested axis.
*/
private static int getMinOfSubregion(NBTTagCompound nbt, String subReg, String s) {
int a = nbt.getCompoundTag("Regions").getCompoundTag(subReg).getCompoundTag("Position").getInteger(s);
int b = nbt.getCompoundTag("Regions").getCompoundTag(subReg).getCompoundTag("Size").getInteger(s);
if (b < 0) {
b++;
}
return Math.min(a, a + b);
}
/**
* @param blockStatePalette List of all different block types used in the schematic.
* @return Array of BlockStates.
*/
private static IBlockState[] getBlockList(NBTTagList blockStatePalette) {
IBlockState[] blockList = new IBlockState[blockStatePalette.tagCount()];
for (int i = 0; i < blockStatePalette.tagCount(); i++) {
Block block = Block.REGISTRY.getObject(new ResourceLocation((((NBTTagCompound) blockStatePalette.get(i)).getString("Name"))));
NBTTagCompound properties = ((NBTTagCompound) blockStatePalette.get(i)).getCompoundTag("Properties");
blockList[i] = getBlockState(block, properties);
}
return blockList;
}
/**
* @param block block.
* @param properties List of Properties the block has.
* @return A blockState.
*/
private static IBlockState getBlockState(Block block, NBTTagCompound properties) {
IBlockState blockState = block.getDefaultState();
for (Object key : properties.getKeySet().toArray()) {
IProperty<?> property = block.getBlockState().getProperty((String) key);
String propertyValue = properties.getString((String) key);
if (property != null) {
blockState = setPropertyValue(blockState, property, propertyValue);
}
}
return blockState;
}
/**
* @author Emerson
*/
private static <T extends Comparable<T>> IBlockState setPropertyValue(IBlockState state, IProperty<T> property, String value) {
Optional<T> parsed = property.parseValue(value).toJavaUtil();
if (parsed.isPresent()) {
return state.withProperty(property, parsed.get());
} else {
throw new IllegalArgumentException("Invalid value for property " + property);
}
}
/**
* @param amountOfBlockTypes amount of block types in the schematic.
* @return amount of bits used to encode a block.
*/
private static int getBitsPerBlock(int amountOfBlockTypes) {
return (int) Math.max(2,Math.ceil(Math.log(amountOfBlockTypes) / Math.log(2)));
}
/**
* Calculates the volume of the subregion. As size can be a negative value we take the absolute value of the
* multiplication as the volume still holds a positive amount of blocks.
*
* @return the volume of the subregion.
*/
private static long getVolume(NBTTagCompound nbt, String subReg) {
return Math.abs(
nbt.getCompoundTag("Regions").getCompoundTag(subReg).getCompoundTag("Size").getInteger("x") *
nbt.getCompoundTag("Regions").getCompoundTag(subReg).getCompoundTag("Size").getInteger("y") *
nbt.getCompoundTag("Regions").getCompoundTag(subReg).getCompoundTag("Size").getInteger("z"));
}
/**
* @return array of Long values.
*/
private static long[] getBlockStates(NBTTagCompound nbt, String subReg) {
return ((INBTTagLongArray) nbt.getCompoundTag("Regions").getCompoundTag(subReg).getTag("BlockStates")).getLongArray();
}
/**
* Subregion don't have to be the same size as the enclosing size of the schematic. If they are smaller we check here if the current block is part of the subregion.
*
* @param x coord of the block relative to the minimum corner.
* @param y coord of the block relative to the minimum corner.
* @param z coord of the block relative to the minimum corner.
* @return if the current block is part of the subregion.
*/
private static boolean inSubregion(NBTTagCompound nbt, String subReg, int x, int y, int z) {
return x >= 0 && y >= 0 && z >= 0 &&
x < Math.abs(nbt.getCompoundTag("Regions").getCompoundTag(subReg).getCompoundTag("Size").getInteger("x")) &&
y < Math.abs(nbt.getCompoundTag("Regions").getCompoundTag(subReg).getCompoundTag("Size").getInteger("y")) &&
z < Math.abs(nbt.getCompoundTag("Regions").getCompoundTag(subReg).getCompoundTag("Size").getInteger("z"));
}
/**
* @param s axis.
* @return the lowest coordinate of that axis of the schematic.
*/
private int getMinOfSchematic(String s) {
int n = Integer.MAX_VALUE;
for (String subReg : getRegions(nbt)) {
n = Math.min(n, getMinOfSubregion(nbt, subReg, s));
}
return n;
}
/**
* reads the file data.
*/
private void fillInSchematic() {
for (String subReg : getRegions(nbt)) {
NBTTagList usedBlockTypes = nbt.getCompoundTag("Regions").getCompoundTag(subReg).getTagList("BlockStatePalette", 10);
IBlockState[] blockList = getBlockList(usedBlockTypes);
int bitsPerBlock = getBitsPerBlock(usedBlockTypes.tagCount());
long regionVolume = getVolume(nbt, subReg);
long[] blockStateArray = getBlockStates(nbt, subReg);
LitematicaBitArray bitArray = new LitematicaBitArray(bitsPerBlock, regionVolume, blockStateArray);
writeSubregionIntoSchematic(nbt, subReg, blockList, bitArray);
}
}
/**
* Writes the file data in to the IBlockstate array.
*
* @param blockList list with the different block types used in the schematic.
* @param bitArray bit array that holds the placement pattern.
*/
private void writeSubregionIntoSchematic(NBTTagCompound nbt, String subReg, IBlockState[] blockList, LitematicaBitArray bitArray) {
Vec3i offsetSubregion = new Vec3i(getMinOfSubregion(nbt, subReg, "x"), getMinOfSubregion(nbt, subReg, "y"), getMinOfSubregion(nbt, subReg, "z"));
int index = 0;
for (int y = 0; y < this.y; y++) {
for (int z = 0; z < this.z; z++) {
for (int x = 0; x < this.x; x++) {
if (inSubregion(nbt, subReg, x, y, z)) {
this.states[x - (offsetMinCorner.getX() - offsetSubregion.getX())][z - (offsetMinCorner.getZ() - offsetSubregion.getZ())][y - (offsetMinCorner.getY() - offsetSubregion.getY())] = blockList[bitArray.getAt(index)];
index++;
}
}
}
}
}
/**
* @return offset from the schematic origin to the minimum Corner as a Vec3i.
*/
public Vec3i getOffsetMinCorner() {
return offsetMinCorner;
}
/**
* @return x size of the schematic.
*/
public int getX() {
return this.x;
}
/**
* @return y size of the schematic.
*/
public int getY() {
return this.y;
}
/**
* @return z size of the schematic.
*/
public int getZ() {
return this.z;
}
/**
* @param x position relative to the minimum corner of the schematic.
* @param y position relative to the minimum corner of the schematic.
* @param z position relative to the minimum corner of the schematic.
* @param blockState new blockstate of the block at this position.
*/
public void setDirect(int x, int y, int z, IBlockState blockState) {
this.states[x][z][y] = blockState;
}
/**
* @param rotated if the schematic is rotated by 90°.
* @return a copy of the schematic.
*/
public LitematicaSchematic getCopy(boolean rotated) {
return new LitematicaSchematic(nbt, rotated);
}
/**
* @author maruohon
* Class from the Litematica mod by maruohon
* Usage under LGPLv3 with the permission of the author.
* <a href="https://github.com/maruohon/litematica">...</a>
*/
private static class LitematicaBitArray {
/**
* The long array that is used to store the data for this BitArray.
*/
private final long[] longArray;
/**
* Number of bits a single entry takes up
*/
private final int bitsPerEntry;
/**
* The maximum value for a single entry. This also works as a bitmask for a single entry.
* For instance, if bitsPerEntry were 5, this value would be 31 (ie, {@code 0b00011111}).
*/
private final long maxEntryValue;
/**
* Number of entries in this array (<b>not</b> the length of the long array that internally backs this array)
*/
private final long arraySize;
public LitematicaBitArray(int bitsPerEntryIn, long arraySizeIn, @Nullable long[] longArrayIn) {
Validate.inclusiveBetween(1L, 32L, bitsPerEntryIn);
this.arraySize = arraySizeIn;
this.bitsPerEntry = bitsPerEntryIn;
this.maxEntryValue = (1L << bitsPerEntryIn) - 1L;
if (longArrayIn != null) {
this.longArray = longArrayIn;
} else {
this.longArray = new long[(int) (roundUp(arraySizeIn * (long) bitsPerEntryIn, 64L) / 64L)];
}
}
public static long roundUp(long number, long interval) {
int sign = 1;
if (interval == 0) {
return 0;
} else if (number == 0) {
return interval;
} else {
if (number < 0) {
sign = -1;
}
long i = number % (interval * sign);
return i == 0 ? number : number + (interval * sign) - i;
}
}
public int getAt(long index) {
Validate.inclusiveBetween(0L, this.arraySize - 1L, index);
long startOffset = index * (long) this.bitsPerEntry;
int startArrIndex = (int) (startOffset >> 6); // startOffset / 64
int endArrIndex = (int) (((index + 1L) * (long) this.bitsPerEntry - 1L) >> 6);
int startBitOffset = (int) (startOffset & 0x3F); // startOffset % 64
if (startArrIndex == endArrIndex) {
return (int) (this.longArray[startArrIndex] >>> startBitOffset & this.maxEntryValue);
} else {
int endOffset = 64 - startBitOffset;
return (int) ((this.longArray[startArrIndex] >>> startBitOffset | this.longArray[endArrIndex] << endOffset) & this.maxEntryValue);
}
}
public long size() {
return this.arraySize;
}
}
}

View File

@@ -0,0 +1,215 @@
/*
* 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.utils.schematic.litematica;
import baritone.utils.schematic.format.defaults.LitematicaSchematic;
import fi.dy.masa.litematica.Litematica;
import fi.dy.masa.litematica.data.DataManager;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.Vec3i;
import java.io.File;
/**
* Helper class that provides access or processes data related to Litmatica schematics.
*
* @author rycbar
* @since 28.09.2022
*/
public final class LitematicaHelper {
/**
* @return if Litmatica is installed.
*/
public static boolean isLitematicaPresent() {
try {
Class.forName(Litematica.class.getName());
return true;
} catch (ClassNotFoundException | NoClassDefFoundError ex) {
return false;
}
}
/**
* @return if there are loaded schematics.
*/
public static boolean hasLoadedSchematic() {
return DataManager.getSchematicPlacementManager().getAllSchematicsPlacements().size() > 0;
}
/**
* @param i index of the Schematic in the schematic placement list.
* @return the name of the requested schematic.
*/
public static String getName(int i) {
return DataManager.getSchematicPlacementManager().getAllSchematicsPlacements().get(i).getName();
}
/**
* @param i index of the Schematic in the schematic placement list.
* @return the world coordinates of the schematic origin. This can but does not have to be the minimum corner.
*/
public static Vec3i getOrigin(int i) {
return DataManager.getSchematicPlacementManager().getAllSchematicsPlacements().get(i).getOrigin();
}
/**
* @param i index of the Schematic in the schematic placement list.
* @return Filepath of the schematic file.
*/
public static File getSchematicFile(int i) {
return DataManager.getSchematicPlacementManager().getAllSchematicsPlacements().get(i).getSchematicFile();
}
/**
* @param i index of the Schematic in the schematic placement list.
* @return rotation of the schematic placement.
*/
public static Rotation getRotation(int i) {
return DataManager.getSchematicPlacementManager().getAllSchematicsPlacements().get(i).getRotation();
}
/**
* @param i index of the Schematic in the schematic placement list.
* @return the mirroring of the schematic placement.
*/
public static Mirror getMirror(int i) {
return DataManager.getSchematicPlacementManager().getAllSchematicsPlacements().get(i).getMirror();
}
/**
* @param schematic original schematic.
* @param i index of the Schematic in the schematic placement list.
* @return the minimum corner coordinates of the schematic, after the original schematic got rotated and mirrored.
*/
public static Vec3i getCorrectedOrigin(LitematicaSchematic schematic, int i) {
int x = LitematicaHelper.getOrigin(i).getX();
int y = LitematicaHelper.getOrigin(i).getY();
int z = LitematicaHelper.getOrigin(i).getZ();
int mx = schematic.getOffsetMinCorner().getX();
int my = schematic.getOffsetMinCorner().getY();
int mz = schematic.getOffsetMinCorner().getZ();
int sx = (schematic.getX() - 1) * -1;
int sz = (schematic.getZ() - 1) * -1;
Vec3i correctedOrigin;
Mirror mirror = LitematicaHelper.getMirror(i);
Rotation rotation = LitematicaHelper.getRotation(i);
//todo there has to be a better way to do this but i cant finde it atm
switch (mirror) {
case FRONT_BACK:
case LEFT_RIGHT:
switch ((mirror.ordinal() * 2 + rotation.ordinal()) % 4) {
case 1:
correctedOrigin = new Vec3i(x + (sz - mz), y + my, z + (sx - mx));
break;
case 2:
correctedOrigin = new Vec3i(x + mx, y + my, z + (sz - mz));
break;
case 3:
correctedOrigin = new Vec3i(x + mz, y + my, z + mx);
break;
default:
correctedOrigin = new Vec3i(x + (sx - mx), y + my, z + mz);
break;
}
break;
default:
switch (rotation) {
case CLOCKWISE_90:
correctedOrigin = new Vec3i(x + (sz - mz), y + my, z + mx);
break;
case CLOCKWISE_180:
correctedOrigin = new Vec3i(x + (sx - mx), y + my, z + (sz - mz));
break;
case COUNTERCLOCKWISE_90:
correctedOrigin = new Vec3i(x + mz, y + my, z + (sx - mx));
break;
default:
correctedOrigin = new Vec3i(x + mx, y + my, z + mz);
break;
}
}
return correctedOrigin;
}
/**
* @param in the xyz offsets of the block relative to the schematic minimum corner.
* @param sizeX size of the schematic in the x-axis direction.
* @param sizeZ size of the schematic in the z-axis direction.
* @param mirror the mirroring of the schematic placement.
* @return the corresponding xyz coordinates after mirroring them according to the given mirroring.
*/
public static Vec3i doMirroring(Vec3i in, int sizeX, int sizeZ, Mirror mirror) {
int xOut = in.getX();
int zOut = in.getZ();
if (mirror == Mirror.LEFT_RIGHT) {
zOut = sizeZ - in.getZ();
} else if (mirror == Mirror.FRONT_BACK) {
xOut = sizeX - in.getX();
}
return new Vec3i(xOut, in.getY(), zOut);
}
/**
* @param in the xyz offsets of the block relative to the schematic minimum corner.
* @param sizeX size of the schematic in the x-axis direction.
* @param sizeZ size of the schematic in the z-axis direction.
* @return the corresponding xyz coordinates after rotation them 90° clockwise.
*/
public static Vec3i rotate(Vec3i in, int sizeX, int sizeZ) {
return new Vec3i(sizeX - (sizeX - sizeZ) - in.getZ(), in.getY(), in.getX());
}
/**
* IDFK this just grew and it somehow works. If you understand how, pls tell me.
*
* @param schemIn give in the original schematic.
* @param i index of the Schematic in the schematic placement list.
* @return get it out rotated and mirrored.
*/
public static LitematicaSchematic blackMagicFuckery(LitematicaSchematic schemIn, int i) {
LitematicaSchematic tempSchem = schemIn.getCopy(LitematicaHelper.getRotation(i).ordinal() % 2 == 1);
for (int yCounter = 0; yCounter < schemIn.getY(); yCounter++) {
for (int zCounter = 0; zCounter < schemIn.getZ(); zCounter++) {
for (int xCounter = 0; xCounter < schemIn.getX(); xCounter++) {
Vec3i xyzHolder = new Vec3i(xCounter, yCounter, zCounter);
xyzHolder = LitematicaHelper.doMirroring(xyzHolder, schemIn.getX() - 1, schemIn.getZ() - 1, LitematicaHelper.getMirror(i));
for (int turns = 0; turns < LitematicaHelper.getRotation(i).ordinal(); turns++) {
if ((turns % 2) == 0) {
xyzHolder = LitematicaHelper.rotate(xyzHolder, schemIn.getX() - 1, schemIn.getZ() - 1);
} else {
xyzHolder = LitematicaHelper.rotate(xyzHolder, schemIn.getZ() - 1, schemIn.getX() - 1);
}
}
IBlockState state = schemIn.getDirect(xCounter, yCounter, zCounter);
try {
state = state.withMirror(LitematicaHelper.getMirror(i)).withRotation(LitematicaHelper.getRotation(i));
} catch (NullPointerException e) {
//nothing to worry about it's just a hole in the schematic.
}
tempSchem.setDirect(xyzHolder.getX(), xyzHolder.getY(), xyzHolder.getZ(), state);
}
}
}
return tempSchem;
}
}

View File

@@ -0,0 +1,21 @@
/*
* 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 fi.dy.masa.litematica;
public class Litematica {
}

View File

@@ -0,0 +1,33 @@
/*
* 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 fi.dy.masa.litematica.data;
import fi.dy.masa.litematica.schematic.placement.SchematicPlacementManager;
public class DataManager {
public static final DataManager INSTANCE = new DataManager();
private final SchematicPlacementManager schematicPlacementManager = new SchematicPlacementManager();
private static DataManager getInstance() {
return INSTANCE;
}
public static SchematicPlacementManager getSchematicPlacementManager() {
return getInstance().schematicPlacementManager;
}
}

View File

@@ -0,0 +1,35 @@
/*
* 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 fi.dy.masa.litematica.schematic.placement;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
public class SchematicPlacement extends SchematicPlacementUnloaded {
private Rotation rotation;
private Mirror mirror;
public Rotation getRotation() {
return this.rotation;
}
public Mirror getMirror() {
return this.mirror;
}
}

View File

@@ -0,0 +1,31 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package fi.dy.masa.litematica.schematic.placement;
import java.util.ArrayList;
import java.util.List;
public class SchematicPlacementManager {
private final List<SchematicPlacement> schematicPlacements = new ArrayList<>();
//in case of a java.lang.NoSuchMethodError try change the name of this method to getAllSchematicPlacements()
//there are inconsistencies in the litematica mod about the naming of this method
public List<SchematicPlacement> getAllSchematicsPlacements() {
return schematicPlacements;
}
}

View File

@@ -15,30 +15,29 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.cache;
package fi.dy.masa.litematica.schematic.placement;
import net.minecraft.util.math.BlockPos;
import java.util.Map;
import javax.annotation.Nullable;
import java.io.File;
/**
* @author Brady
* @since 9/23/2018
*/
public interface IContainerMemory {
public class SchematicPlacementUnloaded {
protected String name = "?";
@Nullable
protected File schematicFile;
protected BlockPos origin = BlockPos.ORIGIN;
/**
* Gets a remembered inventory by its block position.
*
* @param pos The position of the container block
* @return The remembered inventory
*/
IRememberedInventory getInventoryByPos(BlockPos pos);
public String getName() {
return this.name;
}
/**
* Gets the map of all block positions to their remembered inventories.
*
* @return Map of block positions to their respective remembered inventories
*/
Map<BlockPos, IRememberedInventory> getRememberedInventories();
@Nullable
public File getSchematicFile() {
return this.schematicFile;
}
public BlockPos getOrigin() {
return this.origin;
}
}