Compare commits

...

184 Commits

Author SHA1 Message Date
leijurv
a9f40fb0e5 Merge pull request #4885 from Skylandia/tripwire-support
Allow pathing through tripwires
2025-10-16 11:12:38 -07:00
Skylandia
521303b9e4 allow the user to ignore tripwires on the path 2025-10-08 15:35:02 +13:00
leijurv
d196c649e3 Merge pull request #4752 from Murat65536/bridging-improvements
Bridging Improvements
2025-09-11 15:30:24 -07:00
Murat65536
a56f3cfd86 Clarify yaw distance comment 2025-09-10 21:06:26 -04:00
Murat65536
714e7afce1 More minor formatting changes. 2025-08-30 17:48:19 -04:00
Murat65536
037912871c Adjust order. 2025-08-30 08:21:58 -04:00
Murat65536
ce81d36479 Convert to ternary operators. 2025-08-28 21:44:05 -04:00
Murat65536
f9ae7029c3 Formatting change. 2025-08-28 08:57:49 -04:00
Murat65536
61c0a097bb Add 45 degree intervals to yaw change. 2025-08-28 08:22:17 -04:00
ZacSharp
2a3c22424f Update SETUP.md 2025-08-27 01:28:42 +02:00
ZacSharp
bd14ede064 Update README.md 2025-08-27 01:24:15 +02:00
Murat65536
a2a6769742 Round yaw to 45 degrees when bridging. 2025-08-23 20:25:16 -04:00
leijurv
44909d3140 Merge pull request #4764 from rfresh2/precomputed-data-optimize
reduce PrecomputedData memory usage
2025-08-18 21:21:16 -07:00
rfresh2
b666c92267 use requested style 2025-08-18 14:46:09 -07:00
Murat65536
0eb0e6709a Condense more. 2025-08-17 20:12:22 -04:00
Murat65536
9714fa4fd4 Condense logic into huge lambda. 2025-08-17 20:04:55 -04:00
Murat65536
f1e5c44b85 Replace messy Vec2 with a cleaner record class. Also, remove a messy switch case. 2025-08-17 19:52:14 -04:00
leijurv
ade898d5c6 Merge pull request #4839 from AverWasTaken/patch-1
Remove Elytra from future features
2025-08-16 21:20:18 -07:00
Murat65536
7b5ba80f67 Change to Vec2. 2025-08-06 15:38:53 -04:00
aver
69d91a62be Remove Elytra from future features 2025-08-05 16:44:14 -07:00
Murat65536
102960446d Fix bug. 2025-07-31 18:17:35 -04:00
Murat65536
2ba448c30d Merge remote-tracking branch 'origin/bridging-improvements' into bridging-improvements 2025-07-25 16:41:53 -04:00
Murat65536
9d33858687 Small change. 2025-07-25 16:41:38 -04:00
Murat Bayraktar
1c4c3f3eb6 Merge branch 'cabaletta:1.19.4' into bridging-improvements 2025-07-23 22:02:24 -04:00
leijurv
c1aa2012b9 Merge pull request #4740 from Murat65536/safewalk-update
Let external safewalk handle being safe.
2025-07-24 02:01:55 +02:00
Murat Bayraktar
9c84fa54c6 Merge branch 'cabaletta:1.19.4' into bridging-improvements 2025-07-23 19:31:44 -04:00
leijurv
95212d6339 Merge pull request #4742 from Murat65536/magma-block-detection
Magma block detection
2025-07-23 20:58:03 +02:00
leijurv
e3160f50de format 2025-07-23 11:57:53 -07:00
Murat65536
1a3d302e46 Clean up. 2025-07-23 00:49:45 -04:00
Murat65536
8ee7a1e39d Small change. 2025-07-23 00:29:03 -04:00
Murat65536
c8dcbeb6f8 Format. 2025-07-22 11:34:56 -04:00
Murat65536
65d0d860dd Reformatting, appeasing leijurv, and fixing stupid mistake. 2025-07-22 01:51:42 -04:00
Murat65536
65182fa2dc Remove movement change. 2025-07-20 18:40:25 -04:00
Murat Bayraktar
8168d1f889 Merge branch 'cabaletta:1.19.4' into safewalk-update 2025-07-20 18:24:01 -04:00
Murat65536
5d8136b02e Simplify. 2025-07-13 10:09:16 -04:00
Murat65536
191155315b Keep original player movement. 2025-07-06 20:25:02 -04:00
Murat Bayraktar
a30e3ce8e3 Merge branch 'cabaletta:1.19.4' into bridging-improvements 2025-07-06 19:44:20 -04:00
Murat65536
83afa1126e Fix. 2025-07-02 16:08:14 -04:00
Murat Bayraktar
7be4d646d9 Merge branch 'cabaletta:1.19.4' into magma-block-detection 2025-06-24 16:37:12 -04:00
leijurv
4d27d56ff5 Merge pull request #4639 from babbaj/fix-packer
fix chuckpacker y bug
2025-06-04 15:15:10 -07:00
Murat65536
72fb0a0d28 Add default to switch case. 2025-05-23 22:04:13 -04:00
Murat65536
cbfb329b94 Add direction-independent movement. 2025-05-23 18:31:34 -04:00
rfresh2
8f8ce30091 reduce PrecomputedData memory usage 2025-05-21 23:54:10 -07:00
leijurv
89b0fd74dd some readme updates, yes i intentionally linked to the baritone discord server three times 2025-05-14 15:48:46 -07:00
Murat65536
053b88d7cd Make cost calculation use settings in CalculationContext. 2025-05-14 15:13:12 -04:00
Murat Bayraktar
091500b002 Merge branch 'cabaletta:1.19.4' into safewalk-update 2025-05-14 19:08:45 +00:00
Murat Bayraktar
8d790ebe74 Merge branch 'cabaletta:1.19.4' into magma-block-detection 2025-05-14 19:07:56 +00:00
Murat65536
1078270eb3 Clean up. 2025-05-13 21:46:37 -04:00
ZacSharp
de0b1f271e Update quick download links 2025-05-13 23:33:25 +02:00
ZacSharp
5ffd3fcf20 Update setup information 2025-05-13 23:29:54 +02:00
ZacSharp
773d753c60 Update quick download links 2025-05-13 21:31:56 +02:00
ZacSharp
647daf23aa v1.9.5
previous commit was mistaken v1.9.4 already exists
2025-05-13 19:35:28 +02:00
ZacSharp
01379f5474 v1.9.4 2025-05-13 19:32:29 +02:00
leijurv
fd49333db6 Merge pull request #4747 from ZacSharp/pr/1.19.4/setting/migrateAllowJumpAt256
Migrate `allowJumpAt256` to `allowJumpAtBuildLimit` in settings files
2025-05-12 13:30:24 -07:00
Murat65536
0378096340 Make Baritone not look forward while bridging. 2025-05-11 18:12:11 -04:00
ZacSharp
31b30e3a31 Migrate allowJumpAt256 to allowJumpAtBuildLimit in settings files 2025-05-10 20:24:26 +02:00
leijurv
0fe8c628c7 Merge pull request #4745 from ZacSharp/pr/1.19.4/misc/bsi/fixWrapperHeight
Fix height vs. max build height mixup
2025-05-10 11:07:24 -07:00
Murat Bayraktar
21954f74a9 Merge branch 'cabaletta:1.19.4' into magma-block-detection 2025-05-10 15:24:44 +00:00
ZacSharp
f86f0ab6cd Fix height vs. max build height mixup 2025-05-10 15:51:20 +02:00
Murat65536
6dd5d843d5 Make magma blocks disallowed if setting is turned off. 2025-05-10 08:53:26 -04:00
Murat Bayraktar
40e83423bc Update build limits (#4736)
* Update minimum build limit

* Update MovementDescend.java to work for any minimum height

* Update RenderCommand.java for dynamic build heights.

* Fix so it actually compiles.

* Small syntax change.

* Simpler formatting

* Fix more height issues.

* Remove allowJumpAt256 as redundant.

* Remove allowJumpAt256 as redundant.

* Update CalculationContext.java

* Update Settings.java

* Update Settings.java

* Deprecate allowJumpAt256.

* Re-introduce build limit jump setting.

* Update MovementParkour.java

* Update CalculationContext.java

* Update Settings.java

* Update CalculationContext.java

* Update src/api/java/baritone/api/Settings.java

Co-authored-by: ZacSharp <68165024+ZacSharp@users.noreply.github.com>

---------

Co-authored-by: Murat65536 <bob65536@proton.me>
Co-authored-by: ZacSharp <68165024+ZacSharp@users.noreply.github.com>
2025-05-09 22:36:17 -07:00
Murat65536
f4b51586e8 Add setting that controls sneaking on magma blocks. 2025-05-09 22:02:22 -04:00
Murat65536
267d677d79 Make MovementDiagonal not account sprint cost reduction on sneak. 2025-05-09 21:09:56 -04:00
Murat65536
0815697d30 Make MovementPillar literally always sneak because why not. 2025-05-09 20:41:19 -04:00
Murat65536
f504d26dfd Add magma block functionality to MovementParkour. 2025-05-09 20:15:36 -04:00
Murat65536
373757a63a Implement MovementFall magma block detection. 2025-05-09 18:53:03 -04:00
Murat65536
7317a5c9c4 Fix ascend. 2025-05-08 20:33:27 -04:00
Murat65536
8eebeb9772 Magma block detection for MovementDiagonal. 2025-05-08 18:51:37 -04:00
Murat65536
292f13d05e Small change. 2025-05-08 18:24:54 -04:00
Murat65536
974a3416d8 Integrate some magma block avoidance functionality. 2025-05-08 18:10:34 -04:00
Murat65536
7568939dfd Let external safewalk handle being safe. 2025-05-06 21:44:59 -04:00
leijurv
d74420b265 Merge pull request #4720 from ZacSharp/pr/1.19.4/commands/preventRemoteCommandExecution
Don't let servers trick users into running arbitrary Baritone commands
2025-04-21 16:23:49 -07:00
ZacSharp
7aab08ae0f Don't let servers trick users into running arbitrary Baritone commands
As of now there shouldn't be any exploitable commands, but better be safe
2025-04-22 00:50:02 +02:00
leijurv
2fc8490c72 Merge pull request #4712 from ZacSharp/pr/1.19.4/misc/moreExceptionMessages
Add messages to more exceptions and improve some existing ones
2025-04-19 00:08:40 -07:00
leijurv
ddc2820418 Merge pull request #4713 from ZacSharp/pr/1.19.4/misc/useMinecraftEyeHeight
Use minecraft method to determine sneaking eye height
2025-04-18 15:30:30 -07:00
ZacSharp
9e1e89b91f Fix ancient comment 2025-04-18 23:34:16 +02:00
ZacSharp
7c4036dfb1 Don't leak coordinates in exceptions 2025-04-18 23:28:39 +02:00
ZacSharp
bbaa602fe9 Use minecraft method to determine sneaking eye height
Co-authored-by: Matthew Herber <matthewherber@sbcglobal.net>
2025-04-18 22:49:03 +02:00
ZacSharp
921822acd7 Add messages to more exceptions and improve some existing ones 2025-04-18 00:58:16 +02:00
leijurv
f019b81bd9 Merge pull request #2527 from ZacSharp/itemFollowing
Item following
2025-03-29 20:42:14 -07:00
leijurv
50df7b2026 Merge pull request #4677 from ZacSharp/pr/1.19.4/misc/backportCurrentLayerAndMenuLinks
Backport #4634 and #4205 to 1.19.4
2025-03-20 14:42:51 -07:00
Jack
92130f1642 Add issues links and link to Discord for ModMenu 2025-03-16 11:17:18 +01:00
Ic3Tank
fd13d5cbdc Expose current layer in IBuilderProcess 2025-03-16 11:14:51 +01:00
ZacSharp
209b51b253 Fix parsing invalid ResourceLocations once again
This is to fix `ItemById` by making `filterPrefixNamespaced` not fail on invalid prefixes
2025-03-15 20:16:06 +01:00
ZacSharp
3fa0f34c1e Remove unused import 2025-03-15 20:14:50 +01:00
ZacSharp
bf0c47c85c Command to pickup items 2025-03-15 20:14:38 +01:00
leijurv
9de3074041 Merge pull request #4662 from ZacSharp/pr/1.19.4/mine/fixCanWalkThroughButAvoidBreaking
Fix `MineProcess` stalling on blocks which are `canWalkThrough` but shouldn't be broken
2025-03-14 11:49:00 -07:00
leijurv
37a95aea97 Merge pull request #4661 from ZacSharp/pr/1.19.4/schematics/betterErrorMessage
Improve error messages from `#build`
2025-03-14 11:48:27 -07:00
leijurv
3116405953 Merge pull request #4660 from ZacSharp/pr/1.19.4/elytra/keepNetherPathfinderClasses
Fix nether-pathfinder with optimized forge/neoforge builds
2025-03-14 11:48:10 -07:00
leijurv
ed4f9cee78 Merge pull request #4659 from ZacSharp/pr/1.19.4/mixin/backportForgeFix
Backport #4138 to 1.19.4
2025-03-14 11:46:35 -07:00
ZacSharp
b8ac867fb9 Break from eye level outwards
We might be standing inside passable blocks (e.g. sugar cane) so the
block at foot level is occluded by the one at eye level.
This does still break if we are standing inside a non-target with a
target above or below.
2025-03-13 19:32:35 +01:00
ZacSharp
3f6c87a8ed Better error message for unsupported formats 2025-03-08 23:35:23 +01:00
ZacSharp
bf08c4fcf4 Improve error messages from #build 2025-02-27 18:36:35 +01:00
ZacSharp
f357eb230b Remove spam 2025-02-27 15:55:09 +01:00
ZacSharp
f3086c2231 Filter blocks where avoidBreaking returns false
shaft-mining checks `avoidBreaking` so not checking it here can cause
Baritone to walk to a position and then do nothing.
2025-02-27 15:36:59 +01:00
ZacSharp
002415425a Slightly rephrase compatibility message
We cannot distinguish between unsupported systems and failures on supported systems
so strongly implying the former is potentially misleading.
2025-02-26 17:05:40 +01:00
ZacSharp
c54d878d1c Fix nether-pathfinder on forge 2025-02-26 17:05:23 +01:00
rfresh2
590f5d98ee fix forge mixin crash
cherry-picked from 7902517663
2025-02-26 16:12:21 +01:00
Babbaj
6cc5420b95 fix chuckpacker y bug 2025-02-09 02:20:47 -05:00
leijurv
849072f8ca Merge pull request #4636 from Lyzev/1.19.4
add(Settings): added settings to control block placement in fluid sources and flowing fluids
2025-02-08 10:57:21 -08:00
Lyzev
59157c1ee0 fix(CostOfPlacingAt): improve fluid placement checks in CalculationContext 2025-02-08 12:15:55 +01:00
leijurv
3c9f5b2c91 Merge pull request #4596 from cattyngmd/1.19.4-follow-target-max-distance
Added followTargetMaxDistance setting
2025-02-07 16:58:17 -08:00
Lyzev
cdfa86c977 add(Settings): added settings to control block placement in fluid sources and flowing fluids 2025-02-06 18:48:51 +01:00
cattyn
64fdad424f added maximum distance setting for FollowProcess 2024-12-28 14:29:05 +03:00
leijurv
a5668532b1 Merge pull request #4587 from ZacSharp/pr/1.19.4/documenation/updateBuildInstructions
Update build instructions
2024-12-21 23:07:03 -08:00
ZacSharp
bac24af90e Update SETUP.md 2024-12-14 16:29:49 +01:00
leijurv
497fb74829 Merge pull request #4560 from rfresh2/litematica-fix-1.19.4
fix litematica remapping error
2024-11-20 20:02:14 -08:00
leijurv
91a1f05ff2 Update README.md 2024-11-20 01:23:03 -08:00
rfresh2
1a258b2bec fix litematica remapping error 2024-11-18 11:20:52 -08:00
leijurv
93dee4fd19 Merge pull request #4532 from babbaj/fix-loops
fix loops in path
2024-10-21 14:03:42 -07:00
Babbaj
f6657846d3 fix loops in path (fixes #4528) 2024-10-21 02:09:31 -04:00
leijurv
db163867df Merge pull request #4531 from ZacSharp/pr/1.19.4/pathing/canWalkOnSoulSand
Allow walking on soul sand once again
2024-10-20 20:02:43 -07:00
leijurv
58fcf328b9 Merge pull request #4530 from ZacSharp/pr/1.19.4/builder/fixPositionOutOfBounds
Handle positions going out of bounds between ticks
2024-10-20 20:01:25 -07:00
leijurv
8e8cfdd2a6 Merge pull request #4529 from ZacSharp/pr/1.19.4/builder/fixEmptyShapeCrash
Don't call `shape.bounds()` on empty shapes
2024-10-20 20:00:53 -07:00
ZacSharp
991d822557 Make soul sand canWalkOn again 2024-10-20 21:23:38 +02:00
ZacSharp
c25b1325da Handle positions going out of bounds between ticks
They also have to be removed rather than ignored because they won't be scanned
again and would stay in `incorrectPositions` indefinitely.
2024-10-20 18:34:17 +02:00
ZacSharp
ea1de44ca8 Don't call shape.bounds() on empty shapes
`minecraft:moving_piston` is the only block I currently know which could cause this to crash.
2024-10-20 18:13:15 +02:00
leijurv
f22f4aed00 Merge pull request #4519 from babbaj/edge-fix
Fix not moving from edge of block
2024-10-15 16:04:17 -07:00
Babbaj
d644c5b754 a bit more elegant 2024-10-15 18:56:46 -04:00
Babbaj
1e2ae34dbe crucial performance optimization 2024-10-15 18:25:42 -04:00
Babbaj
a690e1eca4 prepend feet to the path if start is adjacent to feet 2024-10-14 17:25:20 -04:00
leijurv
d25d6c2611 Merge pull request #4452 from ZacSharp/pr/1.19.4/builder/rotateAndMirrorSchematics
Add settings to rotate/mirror schematics
2024-09-15 23:34:52 -07:00
leijurv
ef72c56833 Merge pull request #4453 from ZacSharp/pr/1.19.4/schematics/litematicaRework
Almost rewrite litematic handling
2024-08-22 11:01:27 -07:00
ZacSharp
7e8c852528 Setting to mirror schematics 2024-08-02 01:42:46 +02:00
ZacSharp
42032890ed Setting to rotate schematics 2024-08-02 01:41:50 +02:00
ZacSharp
6b6931c86d Remove unused stub
The class doesn't even exist in the version of Litematica I'm using so it doesn't
seem to have an effect on descriptor strings in our bytecode. Otherwise my game
would crash.
2024-07-30 19:26:05 +02:00
ZacSharp
b915151ae3 We don't expect any exceptions here anymore 2024-07-30 19:26:05 +02:00
ZacSharp
7609f3082e Keep subregions as separate boxes 2024-07-30 19:26:05 +02:00
ZacSharp
99f9dd1671 Performance 2024-07-30 19:26:05 +02:00
ZacSharp
1a0cca794c Use toString like for schematica 2024-07-30 19:26:04 +02:00
ZacSharp
e71547b9ef Take blocks from the schematic world 2024-07-30 19:26:04 +02:00
ZacSharp
246a246cb7 Less nested schematics 2024-07-30 19:26:04 +02:00
ZacSharp
b87a1fa420 Take data directly from Litematica 2024-07-30 19:25:57 +02:00
ZacSharp
b12c4e9f8c Merge loading steps 2024-07-30 19:17:13 +02:00
ZacSharp
330089f1e2 Shorten / simplify some Litematica related things 2024-07-30 19:17:08 +02:00
leijurv
f6045b7cb4 Merge pull request #4438 from ZacSharp/pr/1.19.4/build/syncMixinAndAsm
Sync mixin and asm versions between common and tweaker
2024-07-28 00:39:37 -07:00
ZacSharp
a07d7d0526 Sync mixin and asm versions between common and tweaker 2024-07-21 13:33:00 +02:00
leijurv
edb433ea6e Merge pull request #4432 from ZacSharp/pr/1.19.4/build/fixClassloaderExclusion
Move `BaritoneTweaker` to its own package
2024-07-20 11:50:23 -07:00
leijurv
a02704e097 Merge pull request #4430 from ZacSharp/pr/1.19.4/farm/addBamboo
Add bamboo to `FarmProcess` targets
2024-07-20 11:50:12 -07:00
ZacSharp
1947459acf Move tweak class to its own package
Launchwrapper automatically adds a classloader exclusion for every package containing a tweak class, forcing the whole package to load through the parent class loader.
2024-07-14 13:47:52 +02:00
ZacSharp
52aa609ac7 Add bamboo to FarmProcess targets 2024-07-14 10:37:31 +02:00
leijurv
92bc067633 Merge pull request #4395 from wagyourtail/1.19/proguard-cleanup
clean up proguard task
2024-06-19 18:20:08 -07:00
leijurv
64639b377f Merge pull request #4385 from ZacSharp/pr/1.19.4/farm/unhardcodeScanLimit
Unhardcode farm scan limit
2024-06-19 18:18:29 -07:00
Wagyourtail
42c62a0559 clean up proguard task 2024-06-16 23:46:27 -05:00
ZacSharp
b25a6305ce Don't bother testing reachability for far away blocks
This is a massive performance improvement for big farms.
2024-06-09 18:14:41 +02:00
ZacSharp
98e90e72f7 Make farm scan limit configurable 2024-06-09 18:14:41 +02:00
ZacSharp
10851ddf14 Only create scan list when needed 2024-06-09 18:14:40 +02:00
ZacSharp
402079d7db Fail if there is no target position 2024-06-09 18:14:35 +02:00
leijurv
b184141db2 Merge pull request #4374 from ZacSharp/pr/1.19.4/guiclick/removeLogspam
Remove logspam from `GuiClick`
2024-06-07 00:45:33 -07:00
ZacSharp
f9a8aa0c2b Remove logspam 2024-05-26 03:19:35 +02:00
leijurv
0c09441154 Merge pull request #4324 from ZacSharp/pr/1.19.4/setting/fixRecursiveParserType
Fix recursive setting parsers
2024-04-24 12:50:21 -07:00
leijurv
69d3bc0c2e Merge pull request #4320 from rfresh2/instabreak-fix
don't apply block break delay to insta-breaks
2024-04-24 12:50:06 -07:00
leijurv
b31e0a87cb Merge pull request #4333 from ZacSharp/pr/1.19.4/misc/toolset/fixHardnessCrash
Fix NPE in break time calculation
2024-04-24 12:49:15 -07:00
ZacSharp
4572b75db7 Fix NPE in break time calculation 2024-04-10 14:03:48 +02:00
rfresh2
15fdbb2312 revert API renaming 2024-04-07 20:30:16 -07:00
ZacSharp
848b7c6de0 Fix recursive parsers
Does not affect existing parsers since all nested parameterized setting types
are `Map<String, List<String>>` so there is no difference between the first
parameter of the inner type and the first parameter of the outer type
2024-04-02 21:32:01 +02:00
rfresh2
2b96a2e463 don't apply block break delay to insta-breaks 2024-04-01 15:21:24 -07:00
leijurv
62b2f81ba1 Merge pull request #4314 from ZacSharp/pr/1.19.4/builder/fixBuildSkipBlocksNPE
Fix NPE
2024-03-28 19:25:58 -07:00
ZacSharp
5826931eea Fix NPE 2024-03-29 03:17:00 +01:00
leijurv
a8119366a1 Merge pull request #4292 from rfresh2/place-delay-patch
align rightClickSpeed setting with actual delay
2024-03-28 16:53:33 -07:00
leijurv
b0575fbe0c Merge pull request #4291 from rfresh2/block-break-delay
Block break delay setting
2024-03-28 16:53:13 -07:00
leijurv
866cf34f50 Merge pull request #4303 from ZacSharp/pr/1.19.4/builder/placeIncorrectBlockPenaltyMultiplier
Add a `placeIncorrectBlockPenaltyMultiplier` setting
2024-03-28 16:52:31 -07:00
leijurv
23908ad14f Merge pull request #4289 from ZacSharp/pr/1.19.4/ci/updateWorkflows
Update workflows
2024-03-28 16:51:43 -07:00
rfresh2
18d3c4c2bd align rightClickSpeed setting with actual delay 2024-03-10 21:05:30 -07:00
rfresh2
faece77e8c align setting value with actual tick delay between breaks 2024-03-10 16:49:59 -07:00
rfresh2
413c11a23e block break delay setting 2024-03-09 15:26:18 -08:00
ZacSharp
4c9253fa5e Add placeIncorrectBlockPenaltyMultiplier builder setting 2024-03-08 17:49:51 +01:00
ZacSharp
d86a34a527 Fix too low bound and log spam 2024-03-08 17:49:45 +01:00
ZacSharp
92aba1b78e Update workflows 2024-03-06 02:26:58 +01:00
ZacSharp
28ba97c3de Move up and fix access modifiers 2024-02-22 14:16:52 +01:00
ZacSharp
24c23e28ec Reduce recursion limit and fix visibility 2024-02-20 21:35:59 +01:00
ZacSharp
2a2842361b Consistently use helper method
and make a safe cast unnecessary
2024-02-20 21:33:53 +01:00
ZacSharp
632e05c4c2 Make buildSkipBlocks use a wrapper schematic 2024-02-20 21:32:55 +01:00
leijurv
4144344acd Merge pull request #4251 from wagyourtail/1.19/fix/feather-crash
Fix feather crashing by catching error
2024-01-23 14:40:28 -08:00
leijurv
e962c39506 Merge pull request #4248 from ZacSharp/pr/1.19.4/mine/unhardcodeMaxOreLocations
Unhardcode `ORE_LOCATIONS_COUNT`
2024-01-23 14:40:02 -08:00
leijurv
48f309ac05 Merge pull request #4247 from ZacSharp/pr/1.19.4/elytra/removeUnsafeCast
Remove unsafe generic cast
2024-01-23 14:39:44 -08:00
leijurv
0688a57a38 Merge pull request #4252 from wagyourtail/1.19/fix/build-fail
fix 1.19 build failing
2024-01-23 11:04:14 -08:00
Wagyourtail
078b3909b3 fix build failing, by making nether pathfinder version consistent 2024-01-23 08:18:58 -07:00
Wagyourtail
d51b23bd1e Fix feather crashing by catching error 2024-01-22 10:39:12 -07:00
ZacSharp
9378f7e8a0 Unhardcode ORE_LOCATIONS_COUNT 2024-01-21 01:32:30 +01:00
ZacSharp
e7e434a95b Remove unsafe generic cast 2024-01-20 23:35:54 +01:00
leijurv
be1203fabb Merge pull request #4244 from wagyourtail/1.19/fix/null-elytra
fix 🪨🧠 preventing null elytra process from working
2024-01-20 08:50:31 -08:00
Wagyourtail
340d2a1d54 fix 🪨🧠 preventing null elytra process from working 2024-01-20 07:53:11 -07:00
leijurv
f84b749ff4 Update README.md 2024-01-06 12:21:52 -08:00
93 changed files with 1586 additions and 829 deletions

View File

@@ -13,12 +13,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up JDK 17
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
@@ -31,13 +31,13 @@ jobs:
run: ./gradlew build -Pmod_version="$(git describe --always --tags --first-parent | cut -c2-)"
- name: Archive Artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Artifacts
path: dist/
- name: Archive mapping.txt
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Mappings
path: mapping/

View File

@@ -11,9 +11,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

View File

@@ -49,4 +49,3 @@ See <a href="https://github.com/cabaletta/baritone/issues">issues</a> for more.
Things it may not ever have, from most likely to least likely =(
- Boats
- Horses (2x3 path instead of 1x2)
- Elytra

View File

@@ -14,6 +14,7 @@
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.19.2-brightgreen.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.19.4-brightgreen.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.20.1-brightgreen.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.21.3-brightgreen.svg" alt="Minecraft"/></a>
</p>
<p align="center">
@@ -58,22 +59,29 @@ Baritone is the pathfinding system used in [Impact](https://impactclient.net/) s
**Quick download links:**
| Forge | Fabric |
|---------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------|
| [1.12.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.2.19/baritone-api-forge-1.2.19.jar) | |
| [1.16.5 Forge](https://github.com/cabaletta/baritone/releases/download/v1.6.5/baritone-api-forge-1.6.5.jar) | [1.16.5 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.6.5/baritone-api-fabric-1.6.5.jar) |
| [1.17.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.7.3/baritone-api-forge-1.7.3.jar) | [1.17.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.7.3/baritone-api-fabric-1.7.3.jar) |
| [1.18.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.8.5/baritone-api-forge-1.8.5.jar) | [1.18.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.8.5/baritone-api-fabric-1.8.5.jar) |
| [1.19.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.4/baritone-api-forge-1.9.4.jar) | [1.19.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.4/baritone-api-fabric-1.9.4.jar) |
| [1.19.3 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-forge-1.9.1.jar) | [1.19.3 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-fabric-1.9.1.jar) |
| [1.19.4 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-forge-1.9.3.jar) | [1.19.4 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-fabric-1.9.3.jar) |
| [1.20.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.10.1/baritone-api-forge-1.10.1.jar) | [1.20.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.10.1/baritone-api-fabric-1.10.1.jar) |
| Forge | Fabric | NeoForge |
|---------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------|
| [1.12.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.2.19/baritone-api-forge-1.2.19.jar) | | |
| [1.16.5 Forge](https://github.com/cabaletta/baritone/releases/download/v1.6.5/baritone-api-forge-1.6.5.jar) | [1.16.5 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.6.5/baritone-api-fabric-1.6.5.jar) | |
| [1.17.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.7.3/baritone-api-forge-1.7.3.jar) | [1.17.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.7.3/baritone-api-fabric-1.7.3.jar) | |
| [1.18.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.8.6/baritone-api-forge-1.8.6.jar) | [1.18.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.8.6/baritone-api-fabric-1.8.6.jar) | |
| [1.19.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.4/baritone-api-forge-1.9.4.jar) | [1.19.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.4/baritone-api-fabric-1.9.4.jar) | |
| [1.19.3 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-forge-1.9.1.jar) | [1.19.3 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-fabric-1.9.1.jar) | |
| [1.19.4 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.5/baritone-api-forge-1.9.5.jar) | [1.19.4 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.5/baritone-api-fabric-1.9.5.jar) | |
| [1.20.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.10.3/baritone-api-forge-1.10.3.jar) | [1.20.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.10.3/baritone-api-fabric-1.10.3.jar) | |
| [1.20.3 Forge](https://github.com/cabaletta/baritone/releases/download/v1.10.4/baritone-api-forge-1.10.4.jar) | [1.20.3 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.10.4/baritone-api-fabric-1.10.4.jar) | [1.20.3 NeoForge](https://github.com/cabaletta/baritone/releases/download/v1.10.4/baritone-api-neoforge-1.10.4.jar) |
| [1.20.4 Forge](https://github.com/cabaletta/baritone/releases/download/v1.10.4/baritone-api-forge-1.10.4.jar) | [1.20.4 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.10.4/baritone-api-fabric-1.10.4.jar) | [1.20.4 NeoForge](https://github.com/cabaletta/baritone/releases/download/v1.10.4/baritone-api-neoforge-1.10.4.jar) |
| [1.21.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.11.2/baritone-api-forge-1.11.2.jar) | [1.21.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.11.2/baritone-api-fabric-1.11.2.jar) | [1.21.1 NeoForge](https://github.com/cabaletta/baritone/releases/download/v1.11.2/baritone-api-neoforge-1.11.2.jar) |
| [1.21.3 Forge](https://github.com/cabaletta/baritone/releases/download/v1.11.1/baritone-api-forge-1.11.1.jar) | [1.21.3 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.11.1/baritone-api-fabric-1.11.1.jar) | [1.21.3 NeoForge](https://github.com/cabaletta/baritone/releases/download/v1.11.1/baritone-api-neoforge-1.11.1.jar) |
| [1.21.4 Forge](https://github.com/cabaletta/baritone/releases/download/v1.13.1/baritone-api-forge-1.13.1.jar) | [1.21.4 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.13.1/baritone-api-fabric-1.13.1.jar) | [1.21.4 NeoForge](https://github.com/cabaletta/baritone/releases/download/v1.13.1/baritone-api-neoforge-1.13.1.jar) |
| [1.21.5 Forge](https://github.com/cabaletta/baritone/releases/download/v1.14.0/baritone-api-forge-1.14.0.jar) | [1.21.5 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.14.0/baritone-api-fabric-1.14.0.jar) | [1.21.5 NeoForge](https://github.com/cabaletta/baritone/releases/download/v1.14.0/baritone-api-neoforge-1.14.0.jar) |
| [1.21.6 Forge](https://github.com/cabaletta/baritone/releases/download/v1.15.0/baritone-api-forge-1.15.0.jar) | [1.21.6 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.15.0/baritone-api-fabric-1.15.0.jar) | [1.21.6 NeoForge](https://github.com/cabaletta/baritone/releases/download/v1.15.0/baritone-api-neoforge-1.15.0.jar) |
| [1.21.7 Forge](https://github.com/cabaletta/baritone/releases/download/v1.15.0/baritone-api-forge-1.15.0.jar) | [1.21.7 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.15.0/baritone-api-fabric-1.15.0.jar) | [1.21.7 NeoForge](https://github.com/cabaletta/baritone/releases/download/v1.15.0/baritone-api-neoforge-1.15.0.jar) |
| [1.21.8 Forge](https://github.com/cabaletta/baritone/releases/download/v1.15.0/baritone-api-forge-1.15.0.jar) | [1.21.8 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.15.0/baritone-api-fabric-1.15.0.jar) | [1.21.8 NeoForge](https://github.com/cabaletta/baritone/releases/download/v1.15.0/baritone-api-neoforge-1.15.0.jar) |
**Message for 2b2t players looking for 1.19/1.20 Baritone** If you like, please try the beta for Baritone Elytra for 2b2t, find it in #announcements of [the Baritone discord](http://discord.gg/s6fRBAUpmr). It supports 1.19.4 and 1.20.1, Forge or Fabric. If you have to see it to believe it, watch [this YouTube video](https://youtu.be/NnSlQi-68eQ).
**How to immediately get started:** Type `#goto 1000 500` in chat to go to x=1000 z=500. Type `#mine diamond_ore` to mine diamond ore. Type `#stop` to stop. For more, read [the usage page](USAGE.md) and/or watch this [tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa). Also try `#elytra` for Elytra flying in the Nether using fireworks ([trailer](https://youtu.be/4bGGPo8yiHo), [usage](https://youtu.be/NnSlQi-68eQ)). For help, join the [Baritone Discord Server](http://discord.gg/s6fRBAUpmr).
**How to immediately get started:** Type `#goto 1000 500` in chat to go to x=1000 z=500. Type `#mine diamond_ore` to mine diamond ore. Type `#stop` to stop. For more, read [the usage page](USAGE.md) and/or watch this [tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa). Also try `#elytra` for Elytra flying in the Nether using fireworks.
For other versions of Minecraft or more complicated situations or for development, see [Installation & setup](SETUP.md). Also consider just installing [Impact](https://impactclient.net/), which comes with Baritone and is easier to install than wrangling with version JSONs and zips. For 1.16.5, [click here](https://www.youtube.com/watch?v=_4eVJ9Qz2J8) and see description. Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it. There's a [showcase video](https://youtu.be/CZkLXWo4Fg4) made by @Adovin#6313 on Baritone which I recommend.
For other versions of Minecraft or more complicated situations or for development, see [Installation & setup](SETUP.md). For 1.16.5, [click here](https://www.youtube.com/watch?v=_4eVJ9Qz2J8) and see description. Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it. There's a [showcase video](https://youtu.be/CZkLXWo4Fg4) made by @Adovin#6313 on Baritone which I recommend. For help, join the [Baritone Discord Server](http://discord.gg/s6fRBAUpmr).
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 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).

View File

@@ -1,78 +1,87 @@
# Installation
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 or the [1.16.5](https://www.dropbox.com/s/i6f292o2i7o9acp/1.16.5-Baritone.zip?dl=1) version.
The easiest way to install Baritone is to install it as Forge/Neoforge/Fabric mod, but if you know how you can also use it with a custom `version.json`
(Examples: [1.14.4](https://www.dropbox.com/s/rkml3hjokd3qv0m/1.14.4-Baritone.zip?dl=1), [1.15.2](https://www.dropbox.com/s/8rx6f0kts9hvd4f/1.15.2-Baritone.zip?dl=1), [1.16.5](https://www.dropbox.com/s/i6f292o2i7o9acp/1.16.5-Baritone.zip?dl=1)).
Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it.
## Prebuilt official releases
These releases are not always completely up to date with latest features, and are only released from `master`. (so if you want `backfill-2` branch for example, you'll have to build it yourself)
Releases are made rarely and are not always up to date with the latest features and bug fixes.
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.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
The mapping between Minecraft versions and major Baritone versions is as follows
| Minecraft version | 1.12 | 1.13 | 1.14 | 1.15 | 1.16 | 1.17 | 1.18 | 1.19 | 1.20 | 1.21 | 1.21.4 | 1.21.5 | 1.21.6 - 1.21.8 |
|-------------------|------|------|------|------|------|------|------|------|-------|-------|--------|--------|------------------|
| Baritone version | v1.2 | v1.3 | v1.4 | v1.5 | v1.6 | v1.7 | v1.8 | v1.9 | v1.10 | v1.11 | v1.13 | v1.14 | v1.15 |
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).
The build is fully deterministic and reproducible, and you can verify that 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).
## Artifacts
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).
Building Baritone will create the final artifacts in the ``dist`` directory. These are the same as the artifacts created in the [releases](https://github.com/cabaletta/baritone/releases).
**The Forge and Fabric releases can simply be added as a Forge/Fabric mods.**
**The Forge, NeoForge and Fabric releases can simply be added as a Forge/Neoforge/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`
If another one of your other mods has a Baritone integration, you want `baritone-api-*-VERSION.jar`.
If you want to report a bug and spare us some effort, you want `baritone-unoptimized-*-VERSION.jar`.
Otherwise, you want `baritone-standalone-*-VERSION.jar`
Here's what the various qualifiers mean
- **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/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/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.
- **Forge/Fabric Unoptimized**: Same as Unoptimized, but packaged for Forge/Fabric.
- **Standalone**: Everything is obfuscated. Other mods cannot use Baritone, but you get a bit of extra performance.
- **Unoptimized**: Nothing is obfuscated. This shouldn't be used in production, but is really helpful for crash reports.
- **No loader**: Loadable as a launchwrapper tweaker against vanilla Minecraft using a custom `version.json`.
- **Forge/Neoforge/Fabric**: Loadable as a standard mod using the respective loader. The fabric build may or may not work on Quilt.
If you build from source you will also find mapping files in the `dist` directory. These contain the renamings done by ProGuard and are useful if you want to read obfuscated stack traces.
## Build it yourself
- Clone or download Baritone
![Image](https://i.imgur.com/kbqBtoN.png)
- If you choose to download, make sure you extract the ZIP archive.
- If you choose to download, make sure you download the correct branch and extract the ZIP archive.
- Follow one of the instruction sets below, based on your preference
## 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 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 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.
The recommended Java versions by Minecraft version are
| Minecraft version | Java version |
|-------------------------------|---------------|
| 1.12.2 - 1.16.5 | 8 |
| 1.17.1 | 16 |
| 1.18.2 - 1.20.4 | 17 |
| 1.20.5 - 1.21.8 | 21 |
Download java: https://adoptium.net/
#### macOS guide
In order to get JDK 8, Try running the following command:
`% /usr/libexec/java_home -V`
If it doesn't work try this guide: https://stackoverflow.com/questions/46513639/how-to-downgrade-java-from-9-to-8-on-a-macos-eclipse-is-not-running-with-java-9
If you see something like
`% 1.8.0_VERSION, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_VERSION.jdk/Contents/Home`
in the list then you've got JDK 8 installed.
In order to get JDK 8 running in the **current terminal window** you will have to run this command:
`% export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)`
To add OpenJDK 8 to your PATH add the export line to the end of your `.zshrc / .bashrc` if you want it to apply to each new terminal. If you're using bash change the .bachrc and if you're using zsh change the .zshrc
To check which java version you are using do `java -version` in a command prompt or terminal.
### Building Baritone
These tasks depend on the minecraft version, but are (for the most part) standard for building mods.
for more details, see [the build ci action](/.github/workflows/gradle_build.yml)
For more details, see [the build ci action](/.github/workflows/gradle_build.yml) of the branch you want to build.
For most branches `gradlew build` should build everything, but there are exceptions and this file might be out of date.
More specifically, on older branches the setup used to be that `gradlew build` builds the tweaker jar
and `gradlew build -Pbaritone.forge_build` / `gradlew build -Pbaritone.fabric_build` are needed to build
for Forge/Fabric instead. And you might have to run `setupDecompWorkspace` first.
## IntelliJ
- Open the project in IntelliJ as a Gradle project
- Refresh the Gradle project (or, to be safe, just restart IntelliJ)
- depending on the minecraft version, you may need to run `setupDecompWorkspace` or `genIntellijRuns` in order to get everything working
- Depending on the minecraft version, you may need to run `setupDecompWorkspace` or `genIntellijRuns` in order to get everything working
## Github Actions
Most branches have a CI workflow at `.github/workflows/gradle_build.yml`. If you fork this repository and enable actions for your fork
you can push a dummy commit to trigger it and have GitHub build Baritone for you.
If the commit you want to build is less than 90 days old, you can also find the corresponding workflow run in
[this list](https://github.com/cabaletta/baritone/actions/workflows/gradle_build.yml) and download the artifacts from there.

View File

@@ -37,7 +37,13 @@ allprojects {
}
group = rootProject.maven_group
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17
sourceCompatibility = targetCompatibility = JavaVersion.toVersion(project.java_version)
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(sourceCompatibility.majorVersion.toInteger()))
}
}
repositories {
maven {
@@ -72,12 +78,10 @@ allprojects {
}
dependencies {
implementation "org.spongepowered:mixin:0.8.5"
implementation "org.ow2.asm:asm:9.3"
// The following line declares the yarn mappings you may select this one as well.
// mappings "net.fabricmc:yarn:1.17.1+build.32:v2"
//launchImplementation('dev.babbaj:nether-pathfinder:1.3.0')
implementation 'dev.babbaj:nether-pathfinder:1.4.1'
compileOnly "org.spongepowered:mixin:${project.mixin_version}"
compileOnly "org.ow2.asm:asm:${project.asm_version}"
implementation "dev.babbaj:nether-pathfinder:${project.nether_pathfinder_version}"
}
unimined.minecraft(sourceSets.main, true) {
@@ -93,7 +97,7 @@ allprojects {
tasks.withType(JavaCompile).configureEach {
it.options.encoding = "UTF-8"
def targetVersion = 17
def targetVersion = project.java_version.toInteger()
if (JavaVersion.current().isJava9Compatible()) {
it.options.release = targetVersion
}

View File

@@ -36,8 +36,8 @@ import java.nio.file.Paths;
class BaritoneGradleTask extends DefaultTask {
protected static final String
PROGUARD_ZIP = "proguard.zip",
PROGUARD_JAR = "proguard.jar",
PROGUARD_ZIP = "proguard-%s.zip",
PROGUARD_JAR = "proguard-%s.jar",
PROGUARD_CONFIG_TEMPLATE = "scripts/proguard.pro",
PROGUARD_CONFIG_DEST = "template.pro",
PROGUARD_API_CONFIG = "api.pro",

View File

@@ -26,6 +26,9 @@ import org.gradle.api.tasks.TaskCollection;
import org.gradle.api.tasks.compile.ForkOptions;
import org.gradle.api.tasks.compile.JavaCompile;
import org.gradle.internal.jvm.Jvm;
import org.gradle.jvm.toolchain.JavaLanguageVersion;
import org.gradle.jvm.toolchain.JavaLauncher;
import org.gradle.jvm.toolchain.JavaToolchainService;
import xyz.wagyourtail.unimined.api.UniminedExtension;
import xyz.wagyourtail.unimined.api.minecraft.MinecraftConfig;
@@ -47,17 +50,10 @@ import java.util.zip.ZipFile;
public class ProguardTask extends BaritoneGradleTask {
@Input
private String url;
private String proguardVersion;
public String getUrl() {
return url;
}
@Input
private String extract;
public String getExtract() {
return extract;
public String getProguardVersion() {
return proguardVersion;
}
private List<String> requiredLibraries;
@@ -99,98 +95,33 @@ public class ProguardTask extends BaritoneGradleTask {
}
private void downloadProguard() throws Exception {
Path proguardZip = getTemporaryFile(PROGUARD_ZIP);
Path proguardZip = getTemporaryFile(String.format(PROGUARD_ZIP, proguardVersion));
if (!Files.exists(proguardZip)) {
write(new URL(this.url).openStream(), proguardZip);
write(new URL(String.format("https://github.com/Guardsquare/proguard/releases/download/v%s/proguard-%s.zip", proguardVersion, proguardVersion)).openStream(), proguardZip);
}
}
private void extractProguard() throws Exception {
Path proguardJar = getTemporaryFile(PROGUARD_JAR);
Path proguardJar = getTemporaryFile(String.format(PROGUARD_JAR, proguardVersion));
if (!Files.exists(proguardJar)) {
ZipFile zipFile = new ZipFile(getTemporaryFile(PROGUARD_ZIP).toFile());
ZipEntry zipJarEntry = zipFile.getEntry(this.extract);
ZipFile zipFile = new ZipFile(getTemporaryFile(String.format(PROGUARD_ZIP, proguardVersion)).toFile());
ZipEntry zipJarEntry = zipFile.getEntry(String.format("proguard-%s/lib/proguard.jar", proguardVersion));
write(zipFile.getInputStream(zipJarEntry), proguardJar);
zipFile.close();
}
}
private String getJavaBinPathForProguard() throws Exception {
String path;
try {
path = findJavaPathByGradleConfig();
if (path != null) return path;
} catch (Exception ex) {
System.err.println("Unable to find java by javaCompile options");
ex.printStackTrace();
private JavaLauncher getJavaLauncherForProguard() {
var toolchains = getProject().getExtensions().getByType(JavaToolchainService.class);
var toolchain = toolchains.launcherFor((spec) -> {
spec.getLanguageVersion().set(JavaLanguageVersion.of(getProject().findProperty("java_version").toString()));
}).getOrNull();
if (toolchain == null) {
throw new IllegalStateException("Java toolchain not found");
}
path = findJavaByGradleCurrentRuntime();
if (path != null) return path;
try {
path = findJavaByJavaHome();
if (path != null) return path;
} catch (Exception ex) {
System.err.println("Unable to find java by JAVA_HOME");
ex.printStackTrace();
}
throw new Exception("Unable to find java to determine ProGuard libraryjars. Please specify forkOptions.executable in javaCompile," +
" JAVA_HOME environment variable, or make sure to run Gradle with the correct JDK (a v1.8 only)");
}
private String findJavaByGradleCurrentRuntime() {
String path = Jvm.current().getJavaExecutable().getAbsolutePath();
System.out.println("Using Gradle's runtime Java for ProGuard");
return path;
}
private String findJavaByJavaHome() {
final String javaHomeEnv = System.getenv("JAVA_HOME");
if (javaHomeEnv != null) {
String path = Jvm.forHome(new File(javaHomeEnv)).getJavaExecutable().getAbsolutePath();
System.out.println("Detected Java path by JAVA_HOME");
return path;
}
return null;
}
private String findJavaPathByGradleConfig() {
final TaskCollection<JavaCompile> javaCompiles = super.getProject().getTasks().withType(JavaCompile.class);
final JavaCompile compileTask = javaCompiles.iterator().next();
final ForkOptions forkOptions = compileTask.getOptions().getForkOptions();
if (forkOptions != null) {
String javacPath = forkOptions.getExecutable();
if (javacPath != null) {
File javacFile = new File(javacPath);
if (javacFile.exists()) {
File[] maybeJava = javacFile.getParentFile().listFiles((dir, name) -> name.equals("java"));
if (maybeJava != null && maybeJava.length > 0) {
String path = maybeJava[0].getAbsolutePath();
System.out.println("Detected Java path by forkOptions");
return path;
}
}
}
}
return null;
}
private boolean validateJavaVersion(String java) {
//TODO: fix for j16
// final JavaVersion javaVersion = new DefaultJvmVersionDetector(new DefaultExecActionFactory(new IdentityFileResolver())).getJavaVersion(java);
//
// if (!javaVersion.getMajorVersion().equals("8")) {
// System.out.println("Failed to validate Java version " + javaVersion.toString() + " [" + java + "] for ProGuard libraryjars");
// // throw new RuntimeException("Java version incorrect: " + javaVersion.getMajorVersion() + " for " + java);
// return false;
// }
//
// System.out.println("Validated Java version " + javaVersion.toString() + " [" + java + "] for ProGuard libraryjars");
return true;
return toolchain;
}
private void generateConfigs() throws Exception {
@@ -284,13 +215,8 @@ public class ProguardTask extends BaritoneGradleTask {
} catch (IOException ignored) {}
}
public void setUrl(String url) {
this.url = url;
}
public void setExtract(String extract) {
this.extract = extract;
public void setProguardVersion(String url) {
this.proguardVersion = url;
}
private void runProguard(Path config) throws Exception {
@@ -299,39 +225,15 @@ public class ProguardTask extends BaritoneGradleTask {
Files.delete(this.proguardOut);
}
// 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.
getProject().javaexec(spec -> {
spec.workingDir(workingDirectory.toFile());
spec.args("@" + workingDirectory.relativize(config));
spec.classpath(getTemporaryFile(String.format(PROGUARD_JAR, proguardVersion)));
Process p = new ProcessBuilder("java", "-jar", proguardJar.toString(), "@" + config.toString())
.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
this.printOutputLog(p.getInputStream(), System.out);
this.printOutputLog(p.getErrorStream(), System.err);
// Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception
int exitCode = p.waitFor();
if (exitCode != 0) {
Thread.sleep(1000);
throw new IllegalStateException("Proguard exited with code " + exitCode);
}
spec.executable(getJavaLauncherForProguard().getExecutablePath().getAsFile());
}).assertNormalExitValue().rethrowFailure();
}
private void printOutputLog(InputStream stream, PrintStream outerr) {
new Thread(() -> {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
String line;
while ((line = reader.readLine()) != null) {
outerr.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}

View File

@@ -71,10 +71,10 @@ public class Determinizer {
ByteArrayOutputStream cancer = new ByteArrayOutputStream();
copy(jarFile.getInputStream(entry), cancer);
String manifest = new String(cancer.toByteArray());
if (!manifest.contains("baritone.launch.BaritoneTweaker")) {
if (!manifest.contains("baritone.launch.tweaker.BaritoneTweaker")) {
throw new IllegalStateException("unable to replace");
}
manifest = manifest.replace("baritone.launch.BaritoneTweaker", "org.spongepowered.asm.launch.MixinTweaker");
manifest = manifest.replace("baritone.launch.tweaker.BaritoneTweaker", "org.spongepowered.asm.launch.MixinTweaker");
jos.write(manifest.getBytes());
} else {
copy(jarFile.getInputStream(entry), jos);

View File

@@ -45,7 +45,7 @@ dependencies {
common sourceSet.output
shadowCommon sourceSet.output
}
include 'dev.babbaj:nether-pathfinder:1.3.0'
include "dev.babbaj:nether-pathfinder:${project.nether_pathfinder_version}"
}
processResources {
@@ -78,8 +78,7 @@ components.java {
}
task proguard(type: ProguardTask) {
url 'https://github.com/Guardsquare/proguard/releases/download/v7.2.1/proguard-7.2.1.zip'
extract 'proguard-7.2.1/lib/proguard.jar'
proguardVersion "7.2.1"
compType "fabric"
}

View File

@@ -11,7 +11,8 @@
],
"contact": {
"homepage": "https://github.com/cabaletta/baritone",
"sources": "https://github.com/cabaletta/baritone"
"sources": "https://github.com/cabaletta/baritone",
"issues": "https://github.com/cabaletta/baritone/issues"
},
"license": "LGPL-3.0",
@@ -27,5 +28,12 @@
"depends": {
"fabricloader": ">=0.11.0",
"minecraft": "1.19.4"
},
"custom": {
"modmenu": {
"links": {
"modmenu.discord": "https://discord.gg/s6fRBAUpmr"
}
}
}
}

View File

@@ -56,7 +56,7 @@ dependencies {
common sourceSet.output
shadowCommon sourceSet.output
}
shadowCommon 'dev.babbaj:nether-pathfinder:1.3.0'
shadowCommon "dev.babbaj:nether-pathfinder:${project.nether_pathfinder_version}"
}
processResources {
@@ -99,8 +99,7 @@ components.java {
}
task proguard(type: ProguardTask) {
url 'https://github.com/Guardsquare/proguard/releases/download/v7.2.1/proguard-7.2.1.zip'
extract 'proguard-7.2.1/lib/proguard.jar'
proguardVersion "7.2.1"
compType "forge"
}

View File

@@ -1,9 +1,20 @@
org.gradle.jvmargs=-Xmx4G
mod_version=1.9.3
mod_version=1.9.5
maven_group=baritone
archives_base_name=baritone
java_version=17
minecraft_version=1.19.4
forge_version=45.0.43
fabric_version=0.14.11
nether_pathfinder_version=1.4.1
// These dependencies are used for common and tweaker
// while mod loaders usually ship their own version
mixin_version=0.8.5
asm_version=9.3

View File

@@ -54,6 +54,11 @@
-dontwarn baritone.utils.schematic.schematica.**
-dontwarn baritone.utils.schematic.litematica.**
# nether-pathfinder uses JNI to acess its own classes
# and some of our builds include it before running proguard
# conservatively keep all of it, even though only PathSegment.<init> is needed
-keep,allowoptimization class dev.babbaj.pathfinder.** { *; }
# Keep - Applications. Keep all application classes, along with their 'main'
# methods.
-keepclasseswithmembers public class * {

View File

@@ -29,6 +29,11 @@ import net.minecraft.network.chat.Component;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.Mirror;
import net.minecraft.world.level.block.Rotation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.*;
import java.lang.annotation.ElementType;
@@ -50,6 +55,7 @@ import java.util.function.Consumer;
* @author leijurv
*/
public final class Settings {
private static final Logger LOGGER = LoggerFactory.getLogger("Baritone");
/**
* Allow Baritone to break blocks
@@ -71,6 +77,16 @@ public final class Settings {
*/
public final Setting<Boolean> allowPlace = new Setting<>(true);
/**
* Allow Baritone to place blocks in fluid source blocks
*/
public final Setting<Boolean> allowPlaceInFluidsSource = new Setting<>(true);
/**
* Allow Baritone to place blocks in flowing fluid
*/
public final Setting<Boolean> allowPlaceInFluidsFlow = new Setting<>(true);
/**
* Allow Baritone to move items in your inventory to your hotbar
*/
@@ -169,6 +185,13 @@ public final class Settings {
* <p>
* Defaults to false because this fails on constantiam. Please let me know if this is ever disabled. Please.
*/
public final Setting<Boolean> allowJumpAtBuildLimit = new Setting<>(false);
/**
* Just here so mods that use the API don't break. Does nothing.
*/
@Deprecated
@JavaOnly
public final Setting<Boolean> allowJumpAt256 = new Setting<>(false);
/**
@@ -214,9 +237,9 @@ public final class Settings {
/**
* Blocks that Baritone will attempt to avoid (Used in avoidance)
*/
public final Setting<List<Block>> blocksToAvoid = new Setting<>(new ArrayList<>(
// Leave Empty by Default
));
public final Setting<List<Block>> blocksToAvoid = new Setting<>(new ArrayList<>(List.of(
Blocks.TRIPWIRE
)));
/**
* Blocks that Baritone is not allowed to break
@@ -382,6 +405,12 @@ public final class Settings {
*/
public final Setting<Float> blockReachDistance = new Setting<>(4.5f);
/**
* How many ticks between breaking a block and starting to break the next block. Default in game is 6 ticks.
* Values under 1 will be clamped. The delay only applies to non-instant (1-tick) breaks.
*/
public final Setting<Integer> blockBreakSpeed = new Setting<>(6);
/**
* How many degrees to randomize the pitch and yaw every tick. Set to 0 to disable
*/
@@ -900,6 +929,13 @@ public final class Settings {
*/
public final Setting<Integer> maxCachedWorldScanCount = new Setting<>(10);
/**
* Mine will not scan for or remember more than this many target locations.
* Note that the number of locations retrieved from cache is additionaly
* limited by {@link #maxCachedWorldScanCount}.
*/
public final Setting<Integer> mineMaxOreLocationsCount = new Setting<>(64);
/**
* Sets the minimum y level whilst mining - set to 0 to turn off.
* if world has negative y values, subtract the min world height to get the value to put here
@@ -957,6 +993,11 @@ public final class Settings {
*/
public final Setting<Boolean> replantNetherWart = new Setting<>(false);
/**
* Farming will scan for at most this many blocks.
*/
public final Setting<Integer> farmMaxScanSize = new Setting<>(256);
/**
* When the cache scan gives less blocks than the maximum threshold (but still above zero), scan the main world too.
* <p>
@@ -1048,6 +1089,11 @@ public final class Settings {
*/
public final Setting<Double> breakCorrectBlockPenaltyMultiplier = new Setting<>(10d);
/**
* Multiply the cost of placing a block that's incorrect in the builder's schematic by this coefficient
*/
public final Setting<Double> placeIncorrectBlockPenaltyMultiplier = new Setting<>(2d);
/**
* When this setting is true, build a schematic with the highest X coordinate being the origin, instead of the lowest
*/
@@ -1063,6 +1109,28 @@ public final class Settings {
*/
public final Setting<Boolean> schematicOrientationZ = new Setting<>(false);
/**
* Rotates the schematic before building it.
* Possible values are
* <ul>
* <li> NONE - No rotation </li>
* <li> CLOCKWISE_90 - Rotate 90° clockwise </li>
* <li> CLOCKWISE_180 - Rotate 180° clockwise </li>
* <li> COUNTERCLOCKWISE_90 - Rotate 270° clockwise </li>
* </ul>
*/
public final Setting<Rotation> buildSchematicRotation = new Setting<>(Rotation.NONE);
/**
* Mirrors the schematic before building it.
* Possible values are
* <ul>
* <li> FRONT_BACK - mirror the schematic along its local x axis </li>
* <li> LEFT_RIGHT - mirror the schematic along its local z axis </li>
* </ul>
*/
public final Setting<Mirror> buildSchematicMirror = new Setting<>(Mirror.NONE);
/**
* The fallback used by the build command when no extension is specified. This may be useful if schematics of a
* particular format are used often, and the user does not wish to have to specify the extension with every usage.
@@ -1174,6 +1242,11 @@ public final class Settings {
*/
public final Setting<Integer> followRadius = new Setting<>(3);
/**
* The maximum distance to the entity you're following
*/
public final Setting<Integer> followTargetMaxDistance = new Setting<>(0);
/**
* Turn this on if your exploration filter is enormous, you don't want it to check if it's done,
* and you are just fine with it just hanging on completion
@@ -1209,8 +1282,12 @@ public final class Settings {
*/
@JavaOnly
public final Setting<Consumer<Component>> logger = new Setting<>((msg) -> {
final GuiMessageTag tag = useMessageTag.value ? Helper.MESSAGE_TAG : null;
Minecraft.getInstance().gui.getChat().addMessage(msg, null, tag);
try {
final GuiMessageTag tag = useMessageTag.value ? Helper.MESSAGE_TAG : null;
Minecraft.getInstance().gui.getChat().addMessage(msg, null, tag);
} catch (Throwable t) {
LOGGER.warn("Failed to log message to chat: " + msg.getString(), t);
}
});
/**
@@ -1473,6 +1550,11 @@ public final class Settings {
*/
public final Setting<Boolean> elytraChatSpam = new Setting<>(false);
/**
* Sneak when magma blocks are under feet
*/
public final Setting<Boolean> allowWalkOnMagmaBlocks = new Setting<>(false);
/**
* A map of lowercase setting field names to their respective setting
*/

View File

@@ -23,17 +23,11 @@ import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Block;
import java.util.regex.Pattern;
import java.util.stream.Stream;
public enum BlockById implements IDatatypeFor<Block> {
INSTANCE;
/**
* Matches (domain:)?name? where domain and name are [a-z0-9_.-]+ and [a-z0-9/_.-]+ respectively.
*/
private static Pattern PATTERN = Pattern.compile("(?:[a-z0-9_.-]+:)?[a-z0-9/_.-]*");
@Override
public Block get(IDatatypeContext ctx) throws CommandException {
ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString());
@@ -48,10 +42,6 @@ public enum BlockById implements IDatatypeFor<Block> {
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
String arg = ctx.getConsumer().getString();
if (!PATTERN.matcher(arg).matches()) {
return Stream.empty();
}
return new TabCompleteHelper()
.append(
BuiltInRegistries.BLOCK.keySet()

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.api.command.datatypes;
import baritone.api.command.exception.CommandException;
import baritone.api.command.helpers.TabCompleteHelper;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import java.util.stream.Stream;
public enum ItemById implements IDatatypeFor<Item> {
INSTANCE;
@Override
public Item get(IDatatypeContext ctx) throws CommandException {
ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString());
Item item;
if ((item = BuiltInRegistries.ITEM.getOptional(id).orElse(null)) == null) {
throw new IllegalArgumentException("No item found by that id");
}
return item;
}
@Override
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
return new TabCompleteHelper()
.append(
BuiltInRegistries.BLOCK.keySet()
.stream()
.map(ResourceLocation::toString)
)
.filterPrefixNamespaced(ctx.getConsumer().getString())
.sortAlphabetically()
.stream();
}
}

View File

@@ -212,7 +212,12 @@ public class TabCompleteHelper {
* @return This {@link TabCompleteHelper}
*/
public TabCompleteHelper filterPrefixNamespaced(String prefix) {
return filterPrefix(new ResourceLocation(prefix).toString());
ResourceLocation loc = ResourceLocation.tryParse(prefix);
if (loc == null) {
stream = Stream.empty();
return this;
}
return filterPrefix(loc.toString());
}
/**

View File

@@ -44,7 +44,7 @@ public class GoalRunAway implements Goal {
public GoalRunAway(double distance, Integer maintainY, BlockPos... from) {
if (from.length == 0) {
throw new IllegalArgumentException();
throw new IllegalArgumentException("Positions to run away from must not be empty");
}
this.from = from;
this.distanceSq = (int) (distance * distance);

View File

@@ -24,6 +24,7 @@ import net.minecraft.core.Vec3i;
import net.minecraft.world.level.block.state.BlockState;
import java.io.File;
import java.util.List;
import java.util.Optional;
/**
* @author Brady
@@ -74,4 +75,17 @@ public interface IBuilderProcess extends IBaritoneProcess {
* cause it to give up. This is updated every tick, but only while the builder process is active.
*/
List<BlockState> getApproxPlaceable();
/**
* Returns the lower bound of the current mining layer if mineInLayers is true.
* If mineInLayers is false, this will return an empty optional.
* @return The lower bound of the current mining layer
*/
Optional<Integer> getMinLayer();
/**
* Returns the upper bound of the current mining layer if mineInLayers is true.
* If mineInLayers is false, this will return an empty optional.
* @return The upper bound of the current mining layer
*/
Optional<Integer> getMaxLayer();
}

View File

@@ -17,9 +17,11 @@
package baritone.api.process;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.ItemStack;
import java.util.List;
import java.util.function.Predicate;
import net.minecraft.world.entity.Entity;
/**
* @author Brady
@@ -34,6 +36,13 @@ public interface IFollowProcess extends IBaritoneProcess {
*/
void follow(Predicate<Entity> filter);
/**
* Try to pick up any items matching this predicate
*
* @param filter the predicate
*/
void pickup(Predicate<ItemStack> filter);
/**
* @return The entities that are currently being followed. null if not currently following, empty if nothing matches the predicate
*/

View File

@@ -21,6 +21,7 @@ import baritone.api.command.registry.Registry;
import baritone.api.schematic.format.ISchematicFormat;
import java.io.File;
import java.util.List;
import java.util.Optional;
/**
@@ -41,4 +42,9 @@ public interface ISchematicSystem {
* @return The corresponding format for the file, {@link Optional#empty()} if no candidates were found.
*/
Optional<ISchematicFormat> getByFile(File file);
/**
* @return A list of file extensions used by supported formats
*/
List<String> getFileExtensions();
}

View File

@@ -0,0 +1,114 @@
/*
* 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.world.level.block.state.BlockState;
import net.minecraft.world.level.block.Mirror;
import java.util.List;
import java.util.stream.Collectors;
public class MirroredSchematic implements ISchematic {
private final ISchematic schematic;
private final Mirror mirror;
public MirroredSchematic(ISchematic schematic, Mirror mirror) {
this.schematic = schematic;
this.mirror = mirror;
}
@Override
public boolean inSchematic(int x, int y, int z, BlockState currentState) {
return schematic.inSchematic(
mirrorX(x, widthX(), mirror),
y,
mirrorZ(z, lengthZ(), mirror),
mirror(currentState, mirror)
);
}
@Override
public BlockState desiredState(int x, int y, int z, BlockState current, List<BlockState> approxPlaceable) {
return mirror(schematic.desiredState(
mirrorX(x, widthX(), mirror),
y,
mirrorZ(z, lengthZ(), mirror),
mirror(current, mirror),
mirror(approxPlaceable, mirror)
), mirror);
}
@Override
public void reset() {
schematic.reset();
}
@Override
public int widthX() {
return schematic.widthX();
}
@Override
public int heightY() {
return schematic.heightY();
}
@Override
public int lengthZ() {
return schematic.lengthZ();
}
private static int mirrorX(int x, int sizeX, Mirror mirror) {
switch (mirror) {
case NONE:
case LEFT_RIGHT:
return x;
case FRONT_BACK:
return sizeX - x - 1;
}
throw new IllegalArgumentException("Unknown mirror");
}
private static int mirrorZ(int z, int sizeZ, Mirror mirror) {
switch (mirror) {
case NONE:
case FRONT_BACK:
return z;
case LEFT_RIGHT:
return sizeZ - z - 1;
}
throw new IllegalArgumentException("Unknown mirror");
}
private static BlockState mirror(BlockState state, Mirror mirror) {
if (state == null) {
return null;
}
return state.mirror(mirror);
}
private static List<BlockState> mirror(List<BlockState> states, Mirror mirror) {
if (states == null) {
return null;
}
return states.stream()
.map(s -> mirror(s, mirror))
.collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,136 @@
/*
* 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.world.level.block.state.BlockState;
import net.minecraft.world.level.block.Rotation;
import java.util.List;
import java.util.stream.Collectors;
public class RotatedSchematic implements ISchematic {
private final ISchematic schematic;
private final Rotation rotation;
private final Rotation inverseRotation;
public RotatedSchematic(ISchematic schematic, Rotation rotation) {
this.schematic = schematic;
this.rotation = rotation;
// I don't think a 14 line switch would improve readability
this.inverseRotation = rotation.getRotated(rotation).getRotated(rotation);
}
@Override
public boolean inSchematic(int x, int y, int z, BlockState currentState) {
return schematic.inSchematic(
rotateX(x, z, widthX(), lengthZ(), inverseRotation),
y,
rotateZ(x, z, widthX(), lengthZ(), inverseRotation),
rotate(currentState, inverseRotation)
);
}
@Override
public BlockState desiredState(int x, int y, int z, BlockState current, List<BlockState> approxPlaceable) {
return rotate(schematic.desiredState(
rotateX(x, z, widthX(), lengthZ(), inverseRotation),
y,
rotateZ(x, z, widthX(), lengthZ(), inverseRotation),
rotate(current, inverseRotation),
rotate(approxPlaceable, inverseRotation)
), rotation);
}
@Override
public void reset() {
schematic.reset();
}
@Override
public int widthX() {
return flipsCoordinates(rotation) ? schematic.lengthZ() : schematic.widthX();
}
@Override
public int heightY() {
return schematic.heightY();
}
@Override
public int lengthZ() {
return flipsCoordinates(rotation) ? schematic.widthX() : schematic.lengthZ();
}
/**
* Wether {@code rotation} swaps the x and z components
*/
private static boolean flipsCoordinates(Rotation rotation) {
return rotation == Rotation.CLOCKWISE_90 || rotation == Rotation.COUNTERCLOCKWISE_90;
}
/**
* The x component of x,y after applying the rotation
*/
private static int rotateX(int x, int z, int sizeX, int sizeZ, Rotation rotation) {
switch (rotation) {
case NONE:
return x;
case CLOCKWISE_90:
return sizeZ - z - 1;
case CLOCKWISE_180:
return sizeX - x - 1;
case COUNTERCLOCKWISE_90:
return z;
}
throw new IllegalArgumentException("Unknown rotation");
}
/**
* The z component of x,y after applying the rotation
*/
private static int rotateZ(int x, int z, int sizeX, int sizeZ, Rotation rotation) {
switch (rotation) {
case NONE:
return z;
case CLOCKWISE_90:
return x;
case CLOCKWISE_180:
return sizeZ - z - 1;
case COUNTERCLOCKWISE_90:
return sizeX - x - 1;
}
throw new IllegalArgumentException("Unknown rotation");
}
private static BlockState rotate(BlockState state, Rotation rotation) {
if (state == null) {
return null;
}
return state.rotate(rotation);
}
private static List<BlockState> rotate(List<BlockState> states, Rotation rotation) {
if (states == null) {
return null;
}
return states.stream()
.map(s -> rotate(s, rotation))
.collect(Collectors.toList());
}
}

View File

@@ -23,6 +23,7 @@ import baritone.api.schematic.IStaticSchematic;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* The base of a {@link ISchematic} file format
@@ -42,4 +43,9 @@ public interface ISchematicFormat {
* @return Whether or not the specified file matches this schematic format
*/
boolean isFileType(File file);
/**
* @return A list of file extensions used by this format
*/
List<String> getFileExtensions();
}

View File

@@ -99,6 +99,14 @@ public interface IPlayerContext {
return new Rotation(player().getYRot(), player().getXRot());
}
/**
* Returns the player's eye height, taking into account whether or not the player is sneaking.
*
* @param ifSneaking Whether or not the player is sneaking
* @return The player's eye height
* @deprecated Use entity.getEyeHeight(Pose.CROUCHING) instead
*/
@Deprecated
static double eyeHeight(boolean ifSneaking) {
return ifSneaking ? 1.27 : 1.62;
}

View File

@@ -18,6 +18,7 @@
package baritone.api.utils;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
@@ -62,6 +63,6 @@ public final class RayTraceUtils {
}
public static Vec3 inferSneakingEyePosition(Entity entity) {
return new Vec3(entity.getX(), entity.getY() + IPlayerContext.eyeHeight(true), entity.getZ());
return new Vec3(entity.getX(), entity.getY() + entity.getEyeHeight(Pose.CROUCHING), entity.getZ());
}
}

View File

@@ -159,6 +159,26 @@ public class Rotation {
return newYaw;
}
/**
* Gets the distance between a starting yaw and an offset yaw.
* Distance can be negative if the offset yaw is behind of the starting yaw.
*
* @param yaw The initial yaw
* @param offsetYaw The offset yaw
* @return The distance between the yaws
*/
public static float yawDistanceFromOffset(float yaw, float offsetYaw) {
if ((yaw > 0 ^ offsetYaw > 0) && ((yaw > 90 || yaw < -90) ^ (offsetYaw > 90 || offsetYaw < -90))) {
if (yaw < 0) {
return 360 + (yaw - offsetYaw);
} else {
return 360 - (yaw - offsetYaw);
}
} else {
return yaw - offsetYaw;
}
}
@Override
public String toString() {
return "Yaw: " + yaw + ", Pitch: " + pitch;

View File

@@ -27,6 +27,9 @@ import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Mirror;
import net.minecraft.world.level.block.Rotation;
import java.awt.*;
import java.io.BufferedReader;
import java.io.BufferedWriter;
@@ -80,6 +83,10 @@ public class SettingsUtil {
String settingName = matcher.group("setting").toLowerCase();
String settingValue = matcher.group("value");
// TODO remove soonish
if ("allowjumpat256".equals(settingName)) {
settingName = "allowjumpatbuildlimit";
}
try {
parseAndApply(settings, settingName, settingValue);
} catch (Exception ex) {
@@ -149,7 +156,7 @@ public class SettingsUtil {
throw new IllegalStateException("Missing " + setting.getValueClass() + " " + setting.getName());
}
return io.toString(new ParserContext(setting), value);
return io.toString(setting.getType(), value);
}
public static String settingValueToString(Settings.Setting setting) throws IllegalArgumentException {
@@ -196,7 +203,7 @@ public class SettingsUtil {
}
Class intendedType = setting.getValueClass();
ISettingParser ioMethod = Parser.getParser(setting.getType());
Object parsed = ioMethod.parse(new ParserContext(setting), settingValue);
Object parsed = ioMethod.parse(setting.getType(), settingValue);
if (!intendedType.isInstance(parsed)) {
throw new IllegalStateException(ioMethod + " parser returned incorrect type, expected " + intendedType + " got " + parsed + " which is " + parsed.getClass());
}
@@ -205,26 +212,13 @@ public class SettingsUtil {
private interface ISettingParser<T> {
T parse(ParserContext context, String raw);
T parse(Type type, String raw);
String toString(ParserContext context, T value);
String toString(Type type, T value);
boolean accepts(Type type);
}
private static class ParserContext {
private final Settings.Setting<?> setting;
private ParserContext(Settings.Setting<?> setting) {
this.setting = setting;
}
private Settings.Setting<?> getSetting() {
return this.setting;
}
}
private enum Parser implements ISettingParser {
DOUBLE(Double.class, Double::parseDouble),
@@ -233,7 +227,8 @@ public class SettingsUtil {
FLOAT(Float.class, Float::parseFloat),
LONG(Long.class, Long::parseLong),
STRING(String.class, String::new),
DIRECTION(Direction.class, Direction::byName),
MIRROR(Mirror.class, Mirror::valueOf, Mirror::name),
ROTATION(Rotation.class, Rotation::valueOf, Rotation::name),
COLOR(
Color.class,
str -> new Color(Integer.parseInt(str.split(",")[0]), Integer.parseInt(str.split(",")[1]), Integer.parseInt(str.split(",")[2])),
@@ -256,21 +251,21 @@ public class SettingsUtil {
),
LIST() {
@Override
public Object parse(ParserContext context, String raw) {
Type type = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
Parser parser = Parser.getParser(type);
public Object parse(Type type, String raw) {
Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0];
Parser parser = Parser.getParser(elementType);
return Stream.of(raw.split(","))
.map(s -> parser.parse(context, s))
.map(s -> parser.parse(elementType, s))
.collect(Collectors.toList());
}
@Override
public String toString(ParserContext context, Object value) {
Type type = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
Parser parser = Parser.getParser(type);
public String toString(Type type, Object value) {
Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0];
Parser parser = Parser.getParser(elementType);
return ((List<?>) value).stream()
.map(o -> parser.toString(context, o))
.map(o -> parser.toString(elementType, o))
.collect(Collectors.joining(","));
}
@@ -281,26 +276,26 @@ public class SettingsUtil {
},
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];
public Object parse(Type type, String raw) {
Type keyType = ((ParameterizedType) type).getActualTypeArguments()[0];
Type valueType = ((ParameterizedType) type).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])));
.collect(Collectors.toMap(s -> keyParser.parse(keyType, s[0]), s -> valueParser.parse(valueType, 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];
public String toString(Type type, Object value) {
Type keyType = ((ParameterizedType) type).getActualTypeArguments()[0];
Type valueType = ((ParameterizedType) type).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()))
.map(o -> keyParser.toString(keyType, o.getKey()) + "->" + valueParser.toString(valueType, o.getValue()))
.collect(Collectors.joining(","));
}
@@ -331,14 +326,14 @@ public class SettingsUtil {
}
@Override
public Object parse(ParserContext context, String raw) {
public Object parse(Type type, String raw) {
Object parsed = this.parser.apply(raw);
Objects.requireNonNull(parsed);
return parsed;
}
@Override
public String toString(ParserContext context, Object value) {
public String toString(Type type, Object value) {
return this.toString.apply(value);
}

View File

@@ -26,8 +26,6 @@ import baritone.behavior.LookBehavior;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.world.entity.player.Abilities;
import net.minecraft.world.item.ElytraItem;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -112,14 +110,14 @@ public class MixinClientPlayerEntity {
method = "aiStep",
at = @At(
value = "INVOKE",
target = "net/minecraft/world/item/ElytraItem.isFlyEnabled(Lnet/minecraft/world/item/ItemStack;)Z"
target = "Lnet/minecraft/client/player/LocalPlayer;tryToStartFallFlying()Z"
)
)
private boolean isFlyEnabled(ItemStack stack) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((LocalPlayer) (Object) this);
private boolean tryToStartFallFlying(final LocalPlayer instance) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(instance);
if (baritone != null && baritone.getPathingBehavior().isPathing()) {
return false;
}
return ElytraItem.isFlyEnabled(stack);
return instance.tryToStartFallFlying();
}
}

View File

@@ -31,6 +31,10 @@ public abstract class MixinPlayerController implements IPlayerControllerMP {
@Override
public abstract void setIsHittingBlock(boolean isHittingBlock);
@Accessor("isDestroying")
@Override
public abstract boolean isHittingBlock();
@Accessor("destroyBlockPos")
@Override
public abstract BlockPos getCurrentBlock();
@@ -38,4 +42,8 @@ public abstract class MixinPlayerController implements IPlayerControllerMP {
@Invoker("ensureHasSentCarriedItem")
@Override
public abstract void callSyncCurrentPlayItem();
@Accessor("destroyDelay")
@Override
public abstract void setDestroyDelay(int destroyDelay);
}

View File

@@ -21,17 +21,19 @@ import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.event.events.ChatEvent;
import baritone.utils.accessor.IGuiScreen;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.Style;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import java.net.URI;
import net.minecraft.client.gui.screens.Screen;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.net.URI;
import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
@Mixin(Screen.class)
public abstract class MixinScreen implements IGuiScreen {
@@ -47,9 +49,13 @@ public abstract class MixinScreen implements IGuiScreen {
if (clickEvent == null) {
return;
}
String command = clickEvent.getValue();
if (command == null || !command.startsWith(FORCE_COMMAND_PREFIX)) {
return;
}
IBaritone baritone = BaritoneAPI.getProvider().getPrimaryBaritone();
if (baritone != null) {
baritone.getGameEventHandler().onSendChatMessage(new ChatEvent(clickEvent.getValue()));
baritone.getGameEventHandler().onSendChatMessage(new ChatEvent(command));
}
cir.setReturnValue(true);
cir.cancel();

View File

@@ -79,7 +79,7 @@ public class Baritone implements IBaritone {
private final ExploreProcess exploreProcess;
private final FarmProcess farmProcess;
private final InventoryPauserProcess inventoryPauserProcess;
private final ElytraProcess elytraProcess;
private final IElytraProcess elytraProcess;
private final PathingControlManager pathingControlManager;
private final SelectionManager selectionManager;

View File

@@ -265,7 +265,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
if (goal == null) {
return false;
}
if (goal.isInGoal(ctx.playerFeet()) || goal.isInGoal(expectedSegmentStart)) {
if (goal.isInGoal(ctx.playerFeet())) {
return false;
}
synchronized (pathPlanLock) {
@@ -553,7 +553,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
});
}
private static AbstractNodeCostSearch createPathfinder(BlockPos start, Goal goal, IPath previous, CalculationContext context) {
private AbstractNodeCostSearch createPathfinder(BlockPos start, Goal goal, IPath previous, CalculationContext context) {
Goal transformed = goal;
if (Baritone.settings().simplifyUnloadedYCoord.value && goal instanceof IGoalRenderPos) {
BlockPos pos = ((IGoalRenderPos) goal).getGoalPos();
@@ -562,7 +562,14 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
}
}
Favoring favoring = new Favoring(context.getBaritone().getPlayerContext(), previous, context);
return new AStarPathFinder(start.getX(), start.getY(), start.getZ(), transformed, favoring, context);
BetterBlockPos feet = ctx.playerFeet();
var realStart = new BetterBlockPos(start);
var sub = feet.subtract(realStart);
if (feet.getY() == realStart.getY() && Math.abs(sub.getX()) <= 1 && Math.abs(sub.getZ()) <= 1) {
realStart = feet;
}
return new AStarPathFinder(realStart, start.getX(), start.getY(), start.getZ(), transformed, favoring, context);
}
@Override

View File

@@ -78,7 +78,7 @@ public final class ChunkPacker {
for (int x = 0; x < 16; x++) {
int index = CachedChunk.getPositionIndex(x, y, z);
BlockState state = bsc.get(x, y1, z);
boolean[] bits = getPathingBlockType(state, chunk, x, y, z).getBits();
boolean[] bits = getPathingBlockType(state, chunk, x, y + chunk.getMinBuildHeight(), z).getBits();
bitSet.set(index, bits[0]);
bitSet.set(index + 1, bits[1]);
Block block = state.getBlock();

View File

@@ -26,11 +26,13 @@ import baritone.api.command.datatypes.RelativeFile;
import baritone.api.command.exception.CommandException;
import baritone.api.command.exception.CommandInvalidStateException;
import baritone.api.utils.BetterBlockPos;
import baritone.utils.schematic.SchematicSystem;
import org.apache.commons.io.FilenameUtils;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.StringJoiner;
import java.util.stream.Stream;
public class BuildCommand extends Command {
@@ -44,10 +46,29 @@ public class BuildCommand extends Command {
@Override
public void execute(String label, IArgConsumer args) throws CommandException {
File file = args.getDatatypePost(RelativeFile.INSTANCE, schematicsDir).getAbsoluteFile();
final File file0 = args.getDatatypePost(RelativeFile.INSTANCE, schematicsDir).getAbsoluteFile();
File file = file0;
if (FilenameUtils.getExtension(file.getAbsolutePath()).isEmpty()) {
file = new File(file.getAbsolutePath() + "." + Baritone.settings().schematicFallbackExtension.value);
}
if (!file.exists()) {
if (file0.exists()) {
throw new CommandInvalidStateException(String.format(
"Cannot load %s because I do not know which schematic format"
+ " that is. Please rename the file to include the correct"
+ " file extension.",
file));
}
throw new CommandInvalidStateException("Cannot find " + file);
}
if (!SchematicSystem.INSTANCE.getByFile(file).isPresent()) {
StringJoiner formats = new StringJoiner(", ");
SchematicSystem.INSTANCE.getFileExtensions().forEach(formats::add);
throw new CommandInvalidStateException(String.format(
"Unsupported schematic format. Reckognized file extensions are: %s",
formats
));
}
BetterBlockPos origin = ctx.playerFeet();
BetterBlockPos buildOrigin;
if (args.hasAny()) {
@@ -59,7 +80,7 @@ public class BuildCommand extends Command {
}
boolean success = baritone.getBuilderProcess().build(file.getName(), file, buildOrigin);
if (!success) {
throw new CommandInvalidStateException("Couldn't load the schematic. Make sure to use the FULL file name, including the extension (e.g. blah.schematic).");
throw new CommandInvalidStateException("Couldn't load the schematic. Either your schematic is corrupt or this is a bug.");
}
logDirect(String.format("Successfully loaded schematic for building\nOrigin: %s", buildOrigin));
}

View File

@@ -53,6 +53,7 @@ public final class DefaultCommands {
new RenderCommand(baritone),
new FarmCommand(baritone),
new FollowCommand(baritone),
new PickupCommand(baritone),
new ExploreFilterCommand(baritone),
new ReloadAllCommand(baritone),
new SaveAllCommand(baritone),

View File

@@ -216,7 +216,7 @@ public class ElytraCommand extends Command {
final String osArch = System.getProperty("os.arch");
final String osName = System.getProperty("os.name");
return String.format(
"Legacy architectures are not supported. Your CPU is %s and your operating system is %s. " +
"Failed loading native library. Your CPU is %s and your operating system is %s. " +
"Supported architectures are 64 bit x86, and 64 bit ARM. Supported operating systems are Windows, " +
"Linux, and Mac",
osArch, osName

View File

@@ -34,18 +34,9 @@ public class LitematicaCommand extends Command {
@Override
public void execute(String label, IArgConsumer args) throws CommandException {
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.");
}
args.requireMax(1);
int schematic = args.hasAny() ? args.getAs(Integer.class) - 1 : 0;
baritone.getBuilderProcess().buildOpenLitematic(schematic);
}
@Override

View File

@@ -0,0 +1,82 @@
/*
* 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.command.Command;
import baritone.api.command.argument.IArgConsumer;
import baritone.api.command.datatypes.ItemById;
import baritone.api.command.exception.CommandException;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
public class PickupCommand extends Command {
public PickupCommand(IBaritone baritone) {
super(baritone, "pickup");
}
@Override
public void execute(String label, IArgConsumer args) throws CommandException {
Set<Item> collecting = new HashSet<>();
while (args.hasAny()) {
Item item = args.getDatatypeFor(ItemById.INSTANCE);
collecting.add(item);
}
if (collecting.isEmpty()) {
baritone.getFollowProcess().pickup(stack -> true);
logDirect("Picking up all items");
} else {
baritone.getFollowProcess().pickup(stack -> collecting.contains(stack.getItem()));
logDirect("Picking up these items:");
collecting.stream().map(BuiltInRegistries.ITEM::getKey).map(ResourceLocation::toString).forEach(this::logDirect);
}
}
@Override
public Stream<String> tabComplete(String label, IArgConsumer args) throws CommandException {
while (args.has(2)) {
if (args.peekDatatypeOrNull(ItemById.INSTANCE) == null) {
return Stream.empty();
}
args.get();
}
return args.tabCompleteDatatype(ItemById.INSTANCE);
}
@Override
public String getShortDesc() {
return "Pickup items";
}
@Override
public List<String> getLongDesc() {
return Arrays.asList(
"Usage:",
"> pickup - Pickup anything",
"> pickup <item1> <item2> <...> - Pickup certain items"
);
}
}

View File

@@ -40,10 +40,10 @@ public class RenderCommand extends Command {
int renderDistance = (ctx.minecraft().options.renderDistance().get() + 1) * 16;
ctx.minecraft().levelRenderer.setBlocksDirty(
origin.x - renderDistance,
0,
ctx.world().getMinBuildHeight(),
origin.z - renderDistance,
origin.x + renderDistance,
255,
ctx.world().getMaxBuildHeight(),
origin.z + renderDistance
);
logDirect("Done");

View File

@@ -227,12 +227,7 @@ public class SelCommand extends Command {
}
}
}
ISchematic schematic = new StaticSchematic() {{
states = blockstates;
x = size.getX();
y = size.getY();
z = size.getZ();
}};
ISchematic schematic = new StaticSchematic(blockstates);
composite.put(schematic, min.x - origin.x, min.y - origin.y, min.z - origin.z);
}
clipboard = composite;

View File

@@ -44,7 +44,7 @@ public class TunnelCommand extends Command {
int width = Integer.parseInt(args.getArgs().get(1).getValue());
int depth = Integer.parseInt(args.getArgs().get(2).getValue());
if (width < 1 || height < 2 || depth < 1 || height > 255) {
if (width < 1 || height < 2 || depth < 1 || height > ctx.world().getMaxBuildHeight()){
logDirect("Width and depth must at least be 1 block; Height must at least be 2 blocks, and cannot be greater than the build limit.");
cont = false;
}

View File

@@ -22,6 +22,7 @@ import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.SettingsUtil;
import baritone.pathing.calc.openset.BinaryHeapOpenSet;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Moves;
@@ -41,8 +42,8 @@ public final class AStarPathFinder extends AbstractNodeCostSearch {
private final Favoring favoring;
private final CalculationContext calcContext;
public AStarPathFinder(int startX, int startY, int startZ, Goal goal, Favoring favoring, CalculationContext context) {
super(startX, startY, startZ, goal, context);
public AStarPathFinder(BetterBlockPos realStart, int startX, int startY, int startZ, Goal goal, Favoring favoring, CalculationContext context) {
super(realStart, startX, startY, startZ, goal, context);
this.favoring = favoring;
this.calcContext = context;
}
@@ -96,7 +97,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch {
numNodes++;
if (goal.isInGoal(currentNode.x, currentNode.y, currentNode.z)) {
logDebug("Took " + (System.currentTimeMillis() - startTime) + "ms, " + numMovementsConsidered + " movements considered");
return Optional.of(new Path(startNode, currentNode, numNodes, goal, calcContext));
return Optional.of(new Path(realStart, startNode, currentNode, numNodes, goal, calcContext));
}
for (Moves moves : allMoves) {
int newX = currentNode.x + moves.xOffset;
@@ -122,17 +123,39 @@ public final class AStarPathFinder extends AbstractNodeCostSearch {
continue;
}
if (actionCost <= 0 || Double.isNaN(actionCost)) {
throw new IllegalStateException(moves + " calculated implausible cost " + actionCost);
throw new IllegalStateException(String.format(
"%s from %s %s %s calculated implausible cost %s",
moves,
SettingsUtil.maybeCensor(currentNode.x),
SettingsUtil.maybeCensor(currentNode.y),
SettingsUtil.maybeCensor(currentNode.z),
actionCost));
}
// check destination after verifying it's not COST_INF -- some movements return a static IMPOSSIBLE object with COST_INF and destination being 0,0,0 to avoid allocating a new result for every failed calculation
// check destination after verifying it's not COST_INF -- some movements return COST_INF without adjusting the destination
if (moves.dynamicXZ && !worldBorder.entirelyContains(res.x, res.z)) { // see issue #218
continue;
}
if (!moves.dynamicXZ && (res.x != newX || res.z != newZ)) {
throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ);
throw new IllegalStateException(String.format(
"%s from %s %s %s ended at x z %s %s instead of %s %s",
moves,
SettingsUtil.maybeCensor(currentNode.x),
SettingsUtil.maybeCensor(currentNode.y),
SettingsUtil.maybeCensor(currentNode.z),
SettingsUtil.maybeCensor(res.x),
SettingsUtil.maybeCensor(res.z),
SettingsUtil.maybeCensor(newX),
SettingsUtil.maybeCensor(newZ)));
}
if (!moves.dynamicY && res.y != currentNode.y + moves.yOffset) {
throw new IllegalStateException(moves + " " + res.y + " " + (currentNode.y + moves.yOffset));
throw new IllegalStateException(String.format(
"%s from %s %s %s ended at y %s instead of %s",
moves,
SettingsUtil.maybeCensor(currentNode.x),
SettingsUtil.maybeCensor(currentNode.y),
SettingsUtil.maybeCensor(currentNode.z),
SettingsUtil.maybeCensor(res.y),
SettingsUtil.maybeCensor(currentNode.y + moves.yOffset)));
}
long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z);
if (isFavoring) {

View File

@@ -36,6 +36,7 @@ import java.util.Optional;
*/
public abstract class AbstractNodeCostSearch implements IPathFinder, Helper {
protected final BetterBlockPos realStart;
protected final int startX;
protected final int startY;
protected final int startZ;
@@ -81,7 +82,8 @@ public abstract class AbstractNodeCostSearch implements IPathFinder, Helper {
*/
protected static final double MIN_IMPROVEMENT = 0.01;
AbstractNodeCostSearch(int startX, int startY, int startZ, Goal goal, CalculationContext context) {
AbstractNodeCostSearch(BetterBlockPos realStart, int startX, int startY, int startZ, Goal goal, CalculationContext context) {
this.realStart = realStart;
this.startX = startX;
this.startY = startY;
this.startZ = startZ;
@@ -177,7 +179,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder, Helper {
@Override
public Optional<IPath> pathToMostRecentNodeConsidered() {
return Optional.ofNullable(mostRecentConsidered).map(node -> new Path(startNode, node, 0, goal, context));
return Optional.ofNullable(mostRecentConsidered).map(node -> new Path(realStart, startNode, node, 0, goal, context));
}
@Override
@@ -208,7 +210,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder, Helper {
System.out.println("Path goes for " + Math.sqrt(dist) + " blocks");
logDebug("A* cost coefficient " + COEFFICIENTS[i]);
}
return Optional.of(new Path(startNode, bestSoFar[i], numNodes, goal, context));
return Optional.of(new Path(realStart, startNode, bestSoFar[i], numNodes, goal, context));
}
}
// instead of returning bestSoFar[0], be less misleading

View File

@@ -27,6 +27,7 @@ import baritone.pathing.movement.Movement;
import baritone.pathing.movement.Moves;
import baritone.pathing.path.CutoffPath;
import baritone.utils.pathing.PathBase;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.Collections;
@@ -68,28 +69,40 @@ class Path extends PathBase {
private volatile boolean verified;
Path(PathNode start, PathNode end, int numNodes, Goal goal, CalculationContext context) {
this.start = new BetterBlockPos(start.x, start.y, start.z);
Path(BetterBlockPos realStart, PathNode start, PathNode end, int numNodes, Goal goal, CalculationContext context) {
this.end = new BetterBlockPos(end.x, end.y, end.z);
this.numNodes = numNodes;
this.movements = new ArrayList<>();
this.goal = goal;
this.context = context;
PathNode current = end;
LinkedList<BetterBlockPos> tempPath = new LinkedList<>();
LinkedList<PathNode> tempNodes = new LinkedList<>();
// Repeatedly inserting to the beginning of an arraylist is O(n^2)
// Instead, do it into a linked list, then convert at the end
List<BetterBlockPos> tempPath = new ArrayList<>();
List<PathNode> tempNodes = new ArrayList<>();
while (current != null) {
tempNodes.addFirst(current);
tempPath.addFirst(new BetterBlockPos(current.x, current.y, current.z));
tempNodes.add(current);
tempPath.add(new BetterBlockPos(current.x, current.y, current.z));
current = current.previous;
}
// Can't directly convert from the PathNode pseudo linked list to an array because we don't know how long it is
// inserting into a LinkedList<E> keeps track of length, then when we addall (which calls .toArray) it's able
// to performantly do that conversion since it knows the length.
this.path = new ArrayList<>(tempPath);
this.nodes = new ArrayList<>(tempNodes);
// If the position the player is at is different from the position we told A* to start from,
// and A* gave us no movements, then add a fake node that will allow a movement to be created
// that gets us to the single position in the path.
// See PathingBehavior#createPathfinder and https://github.com/cabaletta/baritone/pull/4519
var startNodePos = new BetterBlockPos(start.x, start.y, start.z);
if (!realStart.equals(startNodePos) && start.equals(end)) {
this.start = realStart;
PathNode fakeNode = new PathNode(realStart.x, realStart.y, realStart.z, goal);
fakeNode.cost = 0;
tempNodes.add(fakeNode);
tempPath.add(realStart);
} else {
this.start = startNodePos;
}
// Nodes are traversed last to first so we need to reverse the list
this.path = Lists.reverse(tempPath);
this.nodes = Lists.reverse(tempNodes);
}
@Override
@@ -99,7 +112,7 @@ class Path extends PathBase {
private boolean assembleMovements() {
if (path.isEmpty() || !movements.isEmpty()) {
throw new IllegalStateException();
throw new IllegalStateException("Path must not be empty");
}
for (int i = 0; i < path.size() - 1; i++) {
double cost = nodes.get(i + 1).cost - nodes.get(i).cost;
@@ -132,7 +145,7 @@ class Path extends PathBase {
@Override
public IPath postProcess() {
if (verified) {
throw new IllegalStateException();
throw new IllegalStateException("Path must not be verified twice");
}
verified = true;
boolean failed = assembleMovements();
@@ -141,7 +154,7 @@ class Path extends PathBase {
if (failed) { // at least one movement became impossible during calculation
CutoffPath res = new CutoffPath(this, movements().size());
if (res.movements().size() != movements.size()) {
throw new IllegalStateException();
throw new IllegalStateException("Path has wrong size after cutoff");
}
return res;
}
@@ -153,7 +166,8 @@ class Path extends PathBase {
@Override
public List<IMovement> movements() {
if (!verified) {
throw new IllegalStateException();
// edge case note: this is called during verification
throw new IllegalStateException("Path not yet verified");
}
return Collections.unmodifiableList(movements);
}

View File

@@ -20,6 +20,7 @@ package baritone.pathing.calc;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.SettingsUtil;
/**
* A node in the path, containing the cost and steps to get to it.
@@ -68,7 +69,12 @@ public final class PathNode {
this.cost = ActionCosts.COST_INF;
this.estimatedCostToGoal = goal.heuristic(x, y, z);
if (Double.isNaN(estimatedCostToGoal)) {
throw new IllegalStateException(goal + " calculated implausible heuristic");
throw new IllegalStateException(String.format(
"%s calculated implausible heuristic NaN at %s %s %s",
goal,
SettingsUtil.maybeCensor(x),
SettingsUtil.maybeCensor(y),
SettingsUtil.maybeCensor(z)));
}
this.heapPosition = -1;
this.x = x;

View File

@@ -92,7 +92,7 @@ public final class BinaryHeapOpenSet implements IOpenSet {
@Override
public final PathNode removeLowest() {
if (size == 0) {
throw new IllegalStateException();
throw new IllegalStateException("Cannot remove from empty heap");
}
PathNode result = array[1];
PathNode val = array[size];

View File

@@ -63,7 +63,7 @@ public class CalculationContext {
public final List<Block> allowBreakAnyway;
public final boolean allowParkour;
public final boolean allowParkourPlace;
public final boolean allowJumpAt256;
public final boolean allowJumpAtBuildLimit;
public final boolean allowParkourAscend;
public final boolean assumeWalkOnWater;
public boolean allowFallIntoLava;
@@ -79,6 +79,7 @@ public class CalculationContext {
public double backtrackCostFavoringCoefficient;
public double jumpPenalty;
public final double walkOnWaterOnePenalty;
public final boolean allowWalkOnMagmaBlocks;
public final BetterWorldBorder worldBorder;
public final PrecomputedData precomputedData;
@@ -104,7 +105,7 @@ public class CalculationContext {
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.allowJumpAtBuildLimit = Baritone.settings().allowJumpAtBuildLimit.value;
this.allowParkourAscend = Baritone.settings().allowParkourAscend.value;
this.assumeWalkOnWater = Baritone.settings().assumeWalkOnWater.value;
this.allowFallIntoLava = false; // Super secret internal setting for ElytraBehavior
@@ -125,6 +126,7 @@ public class CalculationContext {
this.backtrackCostFavoringCoefficient = Baritone.settings().backtrackCostFavoringCoefficient.value;
this.jumpPenalty = Baritone.settings().jumpPenalty.value;
this.walkOnWaterOnePenalty = Baritone.settings().walkOnWaterOnePenalty.value;
this.allowWalkOnMagmaBlocks = Baritone.settings().allowWalkOnMagmaBlocks.value;
// why cache these things here, why not let the movements just get directly from settings?
// because if some movements are calculated one way and others are calculated another way,
// then you get a wildly inconsistent path that isn't optimal for either scenario.
@@ -161,6 +163,12 @@ public class CalculationContext {
if (!worldBorder.canPlaceAt(x, z)) {
return COST_INF;
}
if (!Baritone.settings().allowPlaceInFluidsSource.value && current.getFluidState().isSource()) {
return COST_INF;
}
if (!Baritone.settings().allowPlaceInFluidsFlow.value && !current.getFluidState().isEmpty() && !current.getFluidState().isSource()) {
return COST_INF;
}
return placeBlockCost;
}

View File

@@ -31,6 +31,7 @@ import baritone.utils.BlockStateInterface;
import baritone.utils.ToolSet;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.level.block.*;
import net.minecraft.world.level.block.piston.MovingPistonBlock;
@@ -50,9 +51,9 @@ import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import java.util.List;
import java.util.Optional;
import java.util.*;
import static baritone.api.utils.RotationUtils.DEG_TO_RAD_F;
import static baritone.pathing.movement.Movement.HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP;
import static baritone.pathing.precompute.Ternary.*;
@@ -140,7 +141,7 @@ public interface MovementHelper extends ActionCosts, Helper {
if (block instanceof AirBlock) {
return YES;
}
if (block instanceof BaseFireBlock || block == Blocks.TRIPWIRE || block == Blocks.COBWEB || block == Blocks.END_PORTAL || block == Blocks.COCOA || block instanceof AbstractSkullBlock || block == Blocks.BUBBLE_COLUMN || block instanceof ShulkerBoxBlock || block instanceof SlabBlock || block instanceof TrapDoorBlock || block == Blocks.HONEY_BLOCK || block == Blocks.END_ROD || block == Blocks.SWEET_BERRY_BUSH || block == Blocks.POINTED_DRIPSTONE || block instanceof AmethystClusterBlock || block instanceof AzaleaBlock) {
if (block instanceof BaseFireBlock || block == Blocks.COBWEB || block == Blocks.END_PORTAL || block == Blocks.COCOA || block instanceof AbstractSkullBlock || block == Blocks.BUBBLE_COLUMN || block instanceof ShulkerBoxBlock || block instanceof SlabBlock || block instanceof TrapDoorBlock || block == Blocks.HONEY_BLOCK || block == Blocks.END_ROD || block == Blocks.SWEET_BERRY_BUSH || block == Blocks.POINTED_DRIPSTONE || block instanceof AmethystClusterBlock || block instanceof AzaleaBlock) {
return NO;
}
if (block == Blocks.BIG_DRIPLEAF) {
@@ -384,7 +385,7 @@ public interface MovementHelper extends ActionCosts, Helper {
static boolean avoidWalkingInto(BlockState state) {
Block block = state.getBlock();
return !state.getFluidState().isEmpty()
|| block == Blocks.MAGMA_BLOCK
|| (block == Blocks.MAGMA_BLOCK && !Baritone.settings().allowWalkOnMagmaBlocks.value)
|| block == Blocks.CACTUS
|| block == Blocks.SWEET_BERRY_BUSH
|| block instanceof BaseFireBlock
@@ -420,7 +421,7 @@ public interface MovementHelper extends ActionCosts, Helper {
static Ternary canWalkOnBlockState(BlockState state) {
Block block = state.getBlock();
if (isBlockNormalCube(state) && block != Blocks.MAGMA_BLOCK && block != Blocks.BUBBLE_COLUMN && block != Blocks.HONEY_BLOCK) {
if (isBlockNormalCube(state) && (block != Blocks.MAGMA_BLOCK || Baritone.settings().allowWalkOnMagmaBlocks.value) && block != Blocks.BUBBLE_COLUMN && block != Blocks.HONEY_BLOCK) {
return YES;
}
if (block instanceof AzaleaBlock) {
@@ -429,7 +430,7 @@ public interface MovementHelper extends ActionCosts, Helper {
if (block == Blocks.LADDER || (block == Blocks.VINE && Baritone.settings().allowVines.value)) { // TODO reconsider this
return YES;
}
if (block == Blocks.FARMLAND || block == Blocks.DIRT_PATH) {
if (block == Blocks.FARMLAND || block == Blocks.DIRT_PATH || block == Blocks.SOUL_SAND) {
return YES;
}
if (block == Blocks.ENDER_CHEST || block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST) {
@@ -658,6 +659,43 @@ public interface MovementHelper extends ActionCosts, Helper {
)).setInput(Input.MOVE_FORWARD, true);
}
static void moveTowardsWithoutRotation(IPlayerContext ctx, MovementState state, float idealYaw) {
MovementOption.getOptions(
Mth.sin(ctx.playerRotations().getYaw() * DEG_TO_RAD_F),
Mth.cos(ctx.playerRotations().getYaw() * DEG_TO_RAD_F),
Baritone.settings().allowSprint.value
).min(Comparator.comparing(option -> option.distanceToSq(
Mth.sin(idealYaw * DEG_TO_RAD_F),
Mth.cos(idealYaw * DEG_TO_RAD_F)
))).ifPresent(selection -> selection.setInputs(state));
}
static void moveTowardsWithoutRotation(IPlayerContext ctx, MovementState state, BlockPos dest) {
float idealYaw = RotationUtils.calcRotationFromVec3d(
ctx.playerHead(),
VecUtils.getBlockPosCenter(dest),
ctx.playerRotations()
).getYaw();
moveTowardsWithoutRotation(ctx, state, idealYaw);
}
static void moveTowardsWithSlightRotation(IPlayerContext ctx, MovementState state, BlockPos dest) {
float idealYaw = RotationUtils.calcRotationFromVec3d(
ctx.playerHead(),
VecUtils.getBlockPosCenter(dest),
ctx.playerRotations()
).getYaw();
float distance = Rotation.yawDistanceFromOffset(ctx.playerRotations().getYaw(), idealYaw) % 45f;
float newYaw = distance > 0f ?
distance > 22.5f ? distance - 45f : distance :
distance < -22.5f ? distance + 45f : distance;
state.setTarget(new MovementTarget(new Rotation(
ctx.playerRotations().getYaw() - newYaw,
ctx.playerRotations().getPitch()
), true));
moveTowardsWithoutRotation(ctx, state, idealYaw);
}
/**
* Returns whether or not the specified block is
* water, regardless of whether or not it is flowing.
@@ -777,7 +815,7 @@ public interface MovementHelper extends ActionCosts, Helper {
if (ctx.getSelectedBlock().isPresent()) {
BlockPos selectedBlock = ctx.getSelectedBlock().get();
Direction side = ((BlockHitResult) ctx.objectMouseOver()).getDirection();
// only way for selectedBlock.equals(placeAt) to be true is if it's replacable
// only way for selectedBlock.equals(placeAt) to be true is if it's replaceable
if (selectedBlock.equals(placeAt) || (MovementHelper.canPlaceAgainst(ctx, selectedBlock) && selectedBlock.relative(side).equals(placeAt))) {
if (wouldSneak) {
state.setInput(Input.SNEAK, true);
@@ -806,4 +844,16 @@ public interface MovementHelper extends ActionCosts, Helper {
b == Blocks.LAVA ||
b == Blocks.WATER;
}
static List<BetterBlockPos> steppingOnBlocks(IPlayerContext ctx) {
List<BetterBlockPos> blocks = new ArrayList<>();
for (byte x = -1; x <= 1; x++) {
for (byte z = -1; z <= 1; z++) {
if (ctx.player().getBoundingBox().intersects(Vec3.atLowerCornerOf(ctx.player().blockPosition()).add(x, 0, z), Vec3.atLowerCornerOf(ctx.player().blockPosition()).add(x + 1, 1, z + 1))) {
blocks.add(new BetterBlockPos(ctx.player().getBlockX() + x, ctx.player().getBlockY() - 1, ctx.player().getBlockZ() + z));
}
}
}
return blocks;
}
}

View File

@@ -0,0 +1,57 @@
/*
* 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.movement;
import baritone.api.utils.input.Input;
import net.minecraft.util.Mth;
import java.util.stream.Stream;
public record MovementOption(Input input1, Input input2, float motionX, float motionZ) {
private static final float SPRINT_MULTIPLIER = 1.3f;
public MovementOption(Input input1, float motionX, float motionZ) {
this(input1, null, motionX, motionZ);
}
public void setInputs(MovementState movementState) {
if (input1 != null) {
movementState.setInput(input1, true);
}
if (input2 != null) {
movementState.setInput(input2, true);
}
}
public float distanceToSq(float otherX, float otherZ) {
return Mth.abs(motionX() - otherX) + Mth.abs(motionZ() - otherZ);
}
public static Stream<MovementOption> getOptions(float motionX, float motionZ, boolean canSprint) {
return Stream.of(
new MovementOption(Input.MOVE_FORWARD, canSprint ? motionX * SPRINT_MULTIPLIER : motionX, canSprint ? motionZ * SPRINT_MULTIPLIER : motionZ),
new MovementOption(Input.MOVE_BACK, -motionX, -motionZ),
new MovementOption(Input.MOVE_LEFT, -motionZ, motionX),
new MovementOption(Input.MOVE_RIGHT, motionZ, -motionX),
new MovementOption(Input.MOVE_FORWARD, Input.MOVE_LEFT, (canSprint ? motionX * SPRINT_MULTIPLIER : motionX) - motionZ, (canSprint ? motionZ * SPRINT_MULTIPLIER : motionZ) + motionX),
new MovementOption(Input.MOVE_FORWARD, Input.MOVE_RIGHT, (canSprint ? motionX * SPRINT_MULTIPLIER : motionX) + motionZ, (canSprint ? motionZ * SPRINT_MULTIPLIER : motionZ) - motionX),
new MovementOption(Input.MOVE_BACK, Input.MOVE_LEFT, -motionX - motionZ, -motionZ + motionX),
new MovementOption(Input.MOVE_BACK, Input.MOVE_RIGHT, -motionX + motionZ, -motionZ - motionX)
);
}
}

View File

@@ -347,7 +347,7 @@ public enum Moves {
public void apply(CalculationContext context, int x, int y, int z, MutableMoveResult result) {
if (dynamicXZ || dynamicY) {
throw new UnsupportedOperationException();
throw new UnsupportedOperationException("Movements with dynamic offset must override `apply`");
}
result.x = x + xOffset;
result.y = y + yOffset;
@@ -356,6 +356,6 @@ public enum Moves {
}
public double cost(CalculationContext context, int x, int y, int z) {
throw new UnsupportedOperationException();
throw new UnsupportedOperationException("Movements must override `cost` or `apply`");
}
}

View File

@@ -131,8 +131,10 @@ public class MovementAscend extends Movement {
}
} else {
// jumpingFromBottomSlab must be false
if (toPlace.getBlock() == Blocks.SOUL_SAND) {
if (toPlace.is(Blocks.SOUL_SAND)) {
walk = WALK_ONE_OVER_SOUL_SAND_COST;
} else if (toPlace.is(Blocks.MAGMA_BLOCK)) {
walk = SNEAK_ONE_BLOCK_COST;
} else {
walk = Math.max(JUMP_ONE_BLOCK_COST, WALK_ONE_BLOCK_COST);
}
@@ -188,6 +190,9 @@ public class MovementAscend extends Movement {
return state;
}
MovementHelper.moveTowards(ctx, state, dest);
state.setInput(Input.SNEAK, Baritone.settings().allowWalkOnMagmaBlocks.value && jumpingOnto.is(Blocks.MAGMA_BLOCK));
if (MovementHelper.isBottomSlab(jumpingOnto) && !MovementHelper.isBottomSlab(BlockStateInterface.get(ctx, src.below()))) {
return state; // don't jump while walking from a non double slab into a bottom slab
}

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;
@@ -147,9 +148,9 @@ public class MovementDescend extends Movement {
int effectiveStartHeight = y;
for (int fallHeight = 3; true; fallHeight++) {
int newY = y - fallHeight;
if (newY < 0) {
if (newY < context.world.getMinBuildHeight()) {
// when pathing in the end, where you could plausibly fall into the void
// this check prevents it from getting the block at y=-1 and crashing
// this check prevents it from getting the block at y=(below whatever the minimum height is) and crashing
return false;
}
boolean reachedMinimum = fallHeight >= context.minFallHeight;
@@ -255,6 +256,9 @@ public class MovementDescend extends Movement {
double x = ctx.player().position().x - (src.getX() + 0.5);
double z = ctx.player().position().z - (src.getZ() + 0.5);
double fromStart = Math.sqrt(x * x + z * z);
state.setInput(Input.SNEAK, Baritone.settings().allowWalkOnMagmaBlocks.value && ctx.world().getBlockState(ctx.player().blockPosition().below()).is(Blocks.MAGMA_BLOCK));
if (!playerFeet.equals(dest) || ab > 0.25) {
if (numTicks++ < 20 && fromStart < 1.25) {
MovementHelper.moveTowards(ctx, state, fakeDest);

View File

@@ -118,6 +118,7 @@ public class MovementDiagonal extends Movement {
BlockState destWalkOn;
boolean descend = false;
boolean frostWalker = false;
boolean sneaking = false;
if (!MovementHelper.canWalkThrough(context, destX, y, destZ, destInto)) {
ascend = true;
if (!context.allowDiagonalAscend || !MovementHelper.canWalkThrough(context, x, y + 2, z) || !MovementHelper.canWalkOn(context, destX, y, destZ, destInto) || !MovementHelper.canWalkThrough(context, destX, y + 2, destZ)) {
@@ -140,8 +141,11 @@ public class MovementDiagonal extends Movement {
}
double multiplier = WALK_ONE_BLOCK_COST;
// For either possible soul sand, that affects half of our walking
if (destWalkOn.getBlock() == Blocks.SOUL_SAND) {
if (destWalkOn.is(Blocks.SOUL_SAND)) {
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
} else if (context.allowWalkOnMagmaBlocks && destWalkOn.is(Blocks.MAGMA_BLOCK)) {
multiplier += (SNEAK_ONE_BLOCK_COST - WALK_ONE_BLOCK_COST) / 2;
sneaking = true;
} else if (frostWalker) {
// frostwalker lets us walk on water without the penalty
} else if (destWalkOn.getBlock() == Blocks.WATER) {
@@ -153,13 +157,16 @@ public class MovementDiagonal extends Movement {
}
if (fromDownBlock == Blocks.SOUL_SAND) {
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
} else if (context.allowWalkOnMagmaBlocks && fromDownBlock.equals(Blocks.MAGMA_BLOCK)) {
multiplier += (SNEAK_ONE_BLOCK_COST - WALK_ONE_BLOCK_COST) / 2;
sneaking = true;
}
BlockState cuttingOver1 = context.get(x, y - 1, destZ);
if (cuttingOver1.getBlock() == Blocks.MAGMA_BLOCK || MovementHelper.isLava(cuttingOver1)) {
if ((!context.allowWalkOnMagmaBlocks && cuttingOver1.is(Blocks.MAGMA_BLOCK)) || MovementHelper.isLava(cuttingOver1)) {
return;
}
BlockState cuttingOver2 = context.get(destX, y - 1, z);
if (cuttingOver2.getBlock() == Blocks.MAGMA_BLOCK || MovementHelper.isLava(cuttingOver2)) {
if ((!context.allowWalkOnMagmaBlocks && cuttingOver1.is(Blocks.MAGMA_BLOCK)) || MovementHelper.isLava(cuttingOver2)) {
return;
}
boolean water = false;
@@ -234,7 +241,7 @@ public class MovementDiagonal extends Movement {
}
} else {
// only can sprint if not edging around
if (context.canSprint && !water) {
if (context.canSprint && !water && !sneaking) {
// If we aren't edging around anything, and we aren't in water
// We can sprint =D
// Don't check for soul sand, since we can sprint on that too
@@ -270,6 +277,7 @@ public class MovementDiagonal extends Movement {
if (sprint()) {
state.setInput(Input.SPRINT, true);
}
state.setInput(Input.SNEAK, Baritone.settings().allowWalkOnMagmaBlocks.value && MovementHelper.steppingOnBlocks(ctx).stream().anyMatch(block -> ctx.world().getBlockState(block).is(Blocks.MAGMA_BLOCK)));
MovementHelper.moveTowards(ctx, state, dest);
return state;
}

View File

@@ -94,6 +94,11 @@ public class MovementFall extends Movement {
Rotation targetRotation = null;
BlockState destState = ctx.world().getBlockState(dest);
Block destBlock = destState.getBlock();
if (ctx.world().getBlockState(dest.below()).is(Blocks.MAGMA_BLOCK) && MovementHelper.steppingOnBlocks(ctx).stream().allMatch(block -> MovementHelper.canWalkThrough(ctx, block))) {
state.setInput(Input.SNEAK, true);
}
boolean isWater = destState.getFluidState().getType() instanceof WaterFluid;
if (!isWater && willPlaceBucket() && !playerFeet.equals(dest)) {
if (!Inventory.isHotbarSlot(ctx.player().getInventory().findSlotMatchingItem(STACK_BUCKET_WATER)) || ctx.world().dimension() == Level.NETHER) {

View File

@@ -64,10 +64,9 @@ public class MovementParkour extends Movement {
if (!context.allowParkour) {
return;
}
if (y == 256 && !context.allowJumpAt256) {
if (!context.allowJumpAtBuildLimit && y >= context.world.getMaxBuildHeight()) {
return;
}
int xDiff = dir.getStepX();
int zDiff = dir.getStepZ();
if (!MovementHelper.fullyPassable(context, x + xDiff, y, z + zDiff)) {
@@ -103,14 +102,14 @@ public class MovementParkour extends Movement {
return; // can't jump out of water
}
int maxJump;
if (standingOn.getBlock() == Blocks.SOUL_SAND) {
if (context.allowWalkOnMagmaBlocks && standingOn.is(Blocks.MAGMA_BLOCK)) {
maxJump = 2;
} else if (standingOn.getBlock() == Blocks.SOUL_SAND) {
maxJump = 2; // 1 block gap
} else if (context.canSprint) {
maxJump = 4;
} else {
if (context.canSprint) {
maxJump = 4;
} else {
maxJump = 3;
}
maxJump = 3;
}
// check parkour jumps from smallest to largest for obstacles/walls and landing positions
@@ -263,6 +262,10 @@ public class MovementParkour extends Movement {
if (dist >= 4 || ascend) {
state.setInput(Input.SPRINT, true);
}
if (Baritone.settings().allowWalkOnMagmaBlocks.value && ctx.world().getBlockState(ctx.playerFeet().below()).is(Blocks.MAGMA_BLOCK)) {
state.setInput(Input.SNEAK, true);
}
MovementHelper.moveTowards(ctx, state, dest);
if (ctx.playerFeet().equals(dest)) {
Block d = BlockStateInterface.getBlock(ctx, dest);

View File

@@ -229,8 +229,7 @@ public class MovementPillar extends Movement {
return state.setStatus(MovementStatus.UNREACHABLE);
}
state.setInput(Input.SNEAK, ctx.player().position().y > dest.getY() || ctx.player().position().y < src.getY() + 0.2D); // delay placement by 1 tick for ncp compatibility
state.setInput(Input.SNEAK, true);
// since (lower down) we only right click once player.isSneaking, and that happens the tick after we request to sneak
double diffX = ctx.player().position().x - (dest.getX() + 0.5);

View File

@@ -85,6 +85,7 @@ public class MovementTraverse extends Movement {
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;
boolean sneaking = false;
if (MovementHelper.isWater(pb0) || MovementHelper.isWater(pb1)) {
WC = context.waterWalkSpeed;
water = true;
@@ -98,6 +99,9 @@ public class MovementTraverse extends Movement {
}
if (srcDownBlock == Blocks.SOUL_SAND) {
WC += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
} else if (context.allowWalkOnMagmaBlocks && srcDownBlock.equals(Blocks.MAGMA_BLOCK)) {
sneaking = true;
WC += (SNEAK_ONE_BLOCK_COST - WALK_ONE_BLOCK_COST) / 2;
}
}
double hardness1 = MovementHelper.getMiningDurationTicks(context, destX, y, destZ, pb1, false);
@@ -106,7 +110,7 @@ public class MovementTraverse extends Movement {
}
double hardness2 = MovementHelper.getMiningDurationTicks(context, destX, y + 1, destZ, pb0, true); // only include falling on the upper block to break
if (hardness1 == 0 && hardness2 == 0) {
if (!water && context.canSprint) {
if (!water && !sneaking && context.canSprint) {
// If there's nothing in the way, and this isn't water, and we aren't sneak placing
// We can sprint =D
// Don't check for soul sand, since we can sprint on that too
@@ -213,12 +217,12 @@ public class MovementTraverse extends Movement {
.setInput(Input.SPRINT, true);
}
//sneak may have been set to true in the PREPPING state while mining an adjacent block
state.setInput(Input.SNEAK, false);
Block fd = BlockStateInterface.get(ctx, src.below()).getBlock();
boolean ladder = fd == Blocks.LADDER || fd == Blocks.VINE;
//sneak may have been set to true in the PREPPING state while mining an adjacent block, but we still want it to be true if the player is about to go on magma
state.setInput(Input.SNEAK, Baritone.settings().allowWalkOnMagmaBlocks.value && MovementHelper.steppingOnBlocks(ctx).stream().anyMatch(block -> ctx.world().getBlockState(block).is(Blocks.MAGMA_BLOCK)));
if (pb0.getBlock() instanceof DoorBlock || pb1.getBlock() instanceof DoorBlock) {
boolean notPassable = pb0.getBlock() instanceof DoorBlock && !MovementHelper.isDoorPassable(ctx, src, dest) || pb1.getBlock() instanceof DoorBlock && !MovementHelper.isDoorPassable(ctx, dest, src);
boolean canOpen = !(Blocks.IRON_DOOR.equals(pb0.getBlock()) || Blocks.IRON_DOOR.equals(pb1.getBlock()));
@@ -296,7 +300,7 @@ public class MovementTraverse extends Movement {
}
}
double dist1 = Math.max(Math.abs(ctx.player().position().x - (dest.getX() + 0.5D)), Math.abs(ctx.player().position().z - (dest.getZ() + 0.5D)));
PlaceResult p = MovementHelper.attemptToPlaceABlock(state, baritone, dest.below(), false, true);
PlaceResult p = MovementHelper.attemptToPlaceABlock(state, baritone, dest.below(), false, !Baritone.settings().assumeSafeWalk.value);
if ((p == PlaceResult.READY_TO_PLACE || dist1 < 0.6) && !Baritone.settings().assumeSafeWalk.value) {
state.setInput(Input.SNEAK, true);
}
@@ -352,9 +356,8 @@ public class MovementTraverse extends Movement {
}
return state;
}
MovementHelper.moveTowards(ctx, state, positionsToBreak[0]);
MovementHelper.moveTowardsWithSlightRotation(ctx, state, dest);
return state;
// TODO MovementManager.moveTowardsBlock(to); // move towards not look at because if we are bridging for a couple blocks in a row, it is faster if we dont spin around and walk forwards then spin around and place backwards for every block
}
}

View File

@@ -455,7 +455,9 @@ public class PathExecutor implements IPathExecutor, Helper {
if (data != null) {
BetterBlockPos fallDest = new BetterBlockPos(data.getB());
if (!path.positions().contains(fallDest)) {
throw new IllegalStateException();
throw new IllegalStateException(String.format(
"Fall override at %s %s %s returned illegal destination %s %s %s",
current.getSrc(), fallDest));
}
if (ctx.playerFeet().equals(fallDest)) {
pathPosition = path.positions().indexOf(fallDest);
@@ -603,7 +605,9 @@ public class PathExecutor implements IPathExecutor, Helper {
}
return SplicedPath.trySplice(path, next.path, false).map(path -> {
if (!path.getDest().equals(next.getPath().getDest())) {
throw new IllegalStateException();
throw new IllegalStateException(String.format(
"Path has end %s instead of %s after splicing",
path.getDest(), next.getPath().getDest()));
}
PathExecutor ret = new PathExecutor(behavior, path);
ret.pathPosition = pathPosition;
@@ -619,7 +623,9 @@ public class PathExecutor implements IPathExecutor, Helper {
int cutoffAmt = Baritone.settings().pathHistoryCutoffAmount.value;
CutoffPath newPath = new CutoffPath(path, cutoffAmt, path.length() - 1);
if (!newPath.getDest().equals(path.getDest())) {
throw new IllegalStateException();
throw new IllegalStateException(String.format(
"Path has end %s instead of %s after trimming its start",
newPath.getDest(), path.getDest()));
}
logDebug("Discarding earliest segment movements, length cut from " + path.length() + " to " + newPath.length());
PathExecutor ret = new PathExecutor(behavior, newPath);

View File

@@ -92,7 +92,7 @@ public class SplicedPath extends PathBase {
}
int positionInSecond = second.positions().indexOf(first.positions().get(firstPositionInSecond));
if (!allowOverlapCutoff && positionInSecond != 0) {
throw new IllegalStateException();
throw new IllegalStateException("Paths to be spliced are overlapping incorrectly");
}
List<BetterBlockPos> positions = new ArrayList<>();
List<IMovement> movements = new ArrayList<>();

View File

@@ -22,46 +22,45 @@ import baritone.utils.BlockStateInterface;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import static baritone.pathing.precompute.Ternary.MAYBE;
import static baritone.pathing.precompute.Ternary.YES;
public class PrecomputedData {
private final int[] data = new int[Block.BLOCK_STATE_REGISTRY.size()];
private final byte[] data = new byte[Block.BLOCK_STATE_REGISTRY.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 static final int FULLY_PASSABLE_MASK = 1 << 5;
private static final int FULLY_PASSABLE_SPECIAL_MASK = 1 << 6;
/**
* byte layout
*
* 7 6 5 4 3 2 1 0
* | | | | | | | |
* unused canWalkOn maybe canWalkThrough maybe fullyPassable maybe completed
*/
private static final byte COMPLETED_MASK = (byte) 1 << 0;
private static final byte FULLY_PASSABLE_MAYBE_MASK = (byte) 1 << 1;
private static final byte FULLY_PASSABLE_MASK = (byte) 1 << 2;
private static final byte CAN_WALK_THROUGH_MAYBE_MASK = (byte) 1 << 3;
private static final byte CAN_WALK_THROUGH_MASK = (byte) 1 << 4;
private static final byte CAN_WALK_ON_MAYBE_MASK = (byte) 1 << 5;
private static final byte CAN_WALK_ON_MASK = (byte) 1 << 6;
private int fillData(int id, BlockState state) {
int blockData = 0;
byte blockData = 0;
Ternary canWalkOnState = MovementHelper.canWalkOnBlockState(state);
if (canWalkOnState == YES) {
blockData |= CAN_WALK_ON_MASK;
}
if (canWalkOnState == MAYBE) {
blockData |= CAN_WALK_ON_SPECIAL_MASK;
switch (canWalkOnState) {
case YES -> blockData |= CAN_WALK_ON_MASK;
case MAYBE -> blockData |= CAN_WALK_ON_MAYBE_MASK;
}
Ternary canWalkThroughState = MovementHelper.canWalkThroughBlockState(state);
if (canWalkThroughState == YES) {
blockData |= CAN_WALK_THROUGH_MASK;
}
if (canWalkThroughState == MAYBE) {
blockData |= CAN_WALK_THROUGH_SPECIAL_MASK;
switch (canWalkThroughState) {
case YES -> blockData |= CAN_WALK_THROUGH_MASK;
case MAYBE -> blockData |= CAN_WALK_THROUGH_MAYBE_MASK;
}
Ternary fullyPassableState = MovementHelper.fullyPassableBlockState(state);
if (fullyPassableState == YES) {
blockData |= FULLY_PASSABLE_MASK;
}
if (fullyPassableState == MAYBE) {
blockData |= FULLY_PASSABLE_SPECIAL_MASK;
switch (fullyPassableState) {
case YES -> blockData |= FULLY_PASSABLE_MASK;
case MAYBE -> blockData |= FULLY_PASSABLE_MAYBE_MASK;
}
blockData |= COMPLETED_MASK;
@@ -78,7 +77,7 @@ public class PrecomputedData {
blockData = fillData(id, state);
}
if ((blockData & CAN_WALK_ON_SPECIAL_MASK) != 0) {
if ((blockData & CAN_WALK_ON_MAYBE_MASK) != 0) {
return MovementHelper.canWalkOnPosition(bsi, x, y, z, state);
} else {
return (blockData & CAN_WALK_ON_MASK) != 0;
@@ -93,7 +92,7 @@ public class PrecomputedData {
blockData = fillData(id, state);
}
if ((blockData & CAN_WALK_THROUGH_SPECIAL_MASK) != 0) {
if ((blockData & CAN_WALK_THROUGH_MAYBE_MASK) != 0) {
return MovementHelper.canWalkThroughPosition(bsi, x, y, z, state);
} else {
return (blockData & CAN_WALK_THROUGH_MASK) != 0;
@@ -108,7 +107,7 @@ public class PrecomputedData {
blockData = fillData(id, state);
}
if ((blockData & FULLY_PASSABLE_SPECIAL_MASK) != 0) {
if ((blockData & FULLY_PASSABLE_MAYBE_MASK) != 0) {
return MovementHelper.fullyPassablePosition(bsi, x, y, z, state);
} else {
return (blockData & FULLY_PASSABLE_MASK) != 0;

View File

@@ -28,7 +28,10 @@ import baritone.api.process.PathingCommandType;
import baritone.api.schematic.FillSchematic;
import baritone.api.schematic.ISchematic;
import baritone.api.schematic.IStaticSchematic;
import baritone.api.schematic.MaskSchematic;
import baritone.api.schematic.SubstituteSchematic;
import baritone.api.schematic.RotatedSchematic;
import baritone.api.schematic.MirroredSchematic;
import baritone.api.schematic.format.ISchematicFormat;
import baritone.api.utils.*;
import baritone.api.utils.input.Input;
@@ -41,7 +44,6 @@ import baritone.utils.PathingCommandContext;
import baritone.utils.schematic.MapArtSchematic;
import baritone.utils.schematic.SelectionSchematic;
import baritone.utils.schematic.SchematicSystem;
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;
@@ -50,7 +52,6 @@ import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Vec3i;
import net.minecraft.nbt.NbtIo;
import net.minecraft.util.Tuple;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.BlockItem;
@@ -75,7 +76,6 @@ import net.minecraft.world.phys.shapes.VoxelShape;
import java.io.File;
import java.io.FileInputStream;
import java.nio.file.Files;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -84,6 +84,14 @@ import static baritone.api.pathing.movement.ActionCosts.COST_INF;
public final class BuilderProcess extends BaritoneProcessHelper implements IBuilderProcess {
private static final Set<Property<?>> ORIENTATION_PROPS =
ImmutableSet.of(
RotatedPillarBlock.AXIS, HorizontalDirectionalBlock.FACING,
StairBlock.FACING, StairBlock.HALF, StairBlock.SHAPE,
PipeBlock.NORTH, PipeBlock.EAST, PipeBlock.SOUTH, PipeBlock.WEST, PipeBlock.UP,
TrapDoorBlock.OPEN, TrapDoorBlock.HALF
);
private HashSet<BetterBlockPos> incorrectPositions;
private LongOpenHashSet observedCompleted; // positions that are completed even if they're out of render distance and we can't make sure right now
private String name;
@@ -110,6 +118,20 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
if (!Baritone.settings().buildSubstitutes.value.isEmpty()) {
this.schematic = new SubstituteSchematic(this.schematic, Baritone.settings().buildSubstitutes.value);
}
if (Baritone.settings().buildSchematicMirror.value != net.minecraft.world.level.block.Mirror.NONE) {
this.schematic = new MirroredSchematic(this.schematic, Baritone.settings().buildSchematicMirror.value);
}
if (Baritone.settings().buildSchematicRotation.value != net.minecraft.world.level.block.Rotation.NONE) {
this.schematic = new RotatedSchematic(this.schematic, Baritone.settings().buildSchematicRotation.value);
}
// TODO this preserves the old behavior, but maybe we should bake the setting value right here
this.schematic = new MaskSchematic(this.schematic) {
@Override
public boolean partOfMask(int x, int y, int z, BlockState current) {
// partOfMask is only called inside the schematic so desiredState is not null
return !Baritone.settings().buildSkipBlocks.value.contains(this.desiredState(x, y, z, current, Collections.emptyList()).getBlock());
}
};
int x = origin.getX();
int y = origin.getY();
int z = origin.getZ();
@@ -168,15 +190,15 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
if (!format.isPresent()) {
return false;
}
ISchematic parsed;
IStaticSchematic parsed;
try {
parsed = format.get().parse(new FileInputStream(schematic));
} catch (Exception e) {
e.printStackTrace();
return false;
}
parsed = applyMapArtAndSelection(origin, (IStaticSchematic) parsed);
build(name, parsed, origin);
ISchematic schem = applyMapArtAndSelection(origin, parsed);
build(name, schem, origin);
return true;
}
@@ -196,17 +218,10 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
if (SchematicaHelper.isSchematicaPresent()) {
Optional<Tuple<IStaticSchematic, BlockPos>> schematic = SchematicaHelper.getOpenSchematic();
if (schematic.isPresent()) {
IStaticSchematic s = schematic.get().getA();
IStaticSchematic raw = schematic.get().getA();
BlockPos origin = schematic.get().getB();
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().getA().toString(),
schem,
origin
);
ISchematic schem = applyMapArtAndSelection(origin, raw);
this.build(raw.toString(), schem, origin);
} else {
logDirect("No schematic currently open");
}
@@ -219,19 +234,13 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
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(NbtIo.readCompressed(Files.newInputStream(LitematicaHelper.getSchematicFile(i).toPath())), false);
Vec3i correctedOrigin = LitematicaHelper.getCorrectedOrigin(schematic1, i);
ISchematic schematic2 = LitematicaHelper.blackMagicFuckery(schematic1, i);
schematic2 = applyMapArtAndSelection(origin, (IStaticSchematic) schematic2);
build(name, schematic2, correctedOrigin);
} catch (Exception e) {
logDirect("Schematic File could not be loaded.");
}
if (LitematicaHelper.hasLoadedSchematic(i)) {
Tuple<IStaticSchematic, Vec3i> schematic = LitematicaHelper.getSchematic(i);
Vec3i correctedOrigin = schematic.getB();
ISchematic schematic2 = applyMapArtAndSelection(correctedOrigin, schematic.getA());
build(schematic.getA().toString(), schematic2, correctedOrigin);
} else {
logDirect("No schematic currently loaded");
logDirect(String.format("List of placements has no entry %s", i + 1));
}
} else {
logDirect("Litematica is not present");
@@ -362,7 +371,11 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
if (!placementPlausible(new BetterBlockPos(x, y, z), toPlace)) {
continue;
}
AABB aabb = placeAgainstState.getShape(ctx.world(), placeAgainstPos).bounds();
VoxelShape shape = placeAgainstState.getShape(ctx.world(), placeAgainstPos);
if (shape.isEmpty()) {
continue;
}
AABB aabb = shape.bounds();
for (Vec3 placementMultiplier : aabbSideMultipliers(against)) {
double placeX = placeAgainstPos.x + aabb.minX * placementMultiplier.x + aabb.maxX * (1 - placementMultiplier.x);
double placeY = placeAgainstPos.y + aabb.minY * placementMultiplier.y + aabb.maxY * (1 - placementMultiplier.y);
@@ -429,7 +442,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
double z = side.getStepZ() == 0 ? 0.5 : (1 + side.getStepZ()) / 2D;
return new Vec3[]{new Vec3(x, 0.25, z), new Vec3(x, 0.75, z)};
default: // null
throw new IllegalStateException();
throw new IllegalStateException("Unexpected side " + side);
}
}
@@ -438,8 +451,8 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return onTick(calcFailed, isSafeToCancel, 0);
}
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel, int recursions) {
if (recursions > 1000) { // onTick calls itself, don't crash
private PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel, int recursions) {
if (recursions > 100) { // onTick calls itself, don't crash
return new PathingCommand(null, PathingCommandType.SET_GOAL_AND_PATH);
}
approxPlaceable = approxPlaceable(36);
@@ -683,8 +696,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
continue;
}
// this is not in render distance
if (!observedCompleted.contains(BetterBlockPos.longHash(blockX, blockY, blockZ))
&& !Baritone.settings().buildSkipBlocks.value.contains(schematic.desiredState(x, y, z, current, this.approxPlaceable).getBlock())) {
if (!observedCompleted.contains(BetterBlockPos.longHash(blockX, blockY, blockZ))) {
// and we've never seen this position be correct
// therefore mark as incorrect
incorrectPositions.add(new BetterBlockPos(blockX, blockY, blockZ));
@@ -707,13 +719,16 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
List<BetterBlockPos> sourceLiquids = new ArrayList<>();
List<BetterBlockPos> flowingLiquids = new ArrayList<>();
Map<BlockState, Integer> missing = new HashMap<>();
List<BetterBlockPos> outOfBounds = new ArrayList<>();
incorrectPositions.forEach(pos -> {
BlockState state = bcc.bsi.get0(pos);
if (state.getBlock() instanceof AirBlock) {
if (containsBlockState(approxPlaceable, bcc.getSchematic(pos.x, pos.y, pos.z, state))) {
BlockState desired = bcc.getSchematic(pos.x, pos.y, pos.z, state);
if (desired == null) {
outOfBounds.add(pos);
} else if (containsBlockState(approxPlaceable, desired)) {
placeable.add(pos);
} else {
BlockState desired = bcc.getSchematic(pos.x, pos.y, pos.z, state);
missing.put(desired, 1 + missing.getOrDefault(desired, 0));
}
} else {
@@ -731,6 +746,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
}
}
});
incorrectPositions.removeAll(outOfBounds);
List<Goal> toBreak = new ArrayList<>();
breakable.forEach(pos -> toBreak.add(breakGoal(pos, bcc)));
List<Goal> toPlace = new ArrayList<>();
@@ -983,6 +999,22 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return paused ? "Builder Paused" : "Building " + name;
}
@Override
public Optional<Integer> getMinLayer() {
if (Baritone.settings().buildInLayers.value) {
return Optional.of(this.layer);
}
return Optional.empty();
}
@Override
public Optional<Integer> getMaxLayer() {
if (Baritone.settings().buildInLayers.value) {
return Optional.of(this.stopAtHeight);
}
return Optional.empty();
}
private List<BlockState> approxPlaceable(int size) {
List<BlockState> result = new ArrayList<>();
for (int i = 0; i < size; i++) {
@@ -1009,15 +1041,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return result;
}
public static final Set<Property<?>> orientationProps =
ImmutableSet.of(
RotatedPillarBlock.AXIS, HorizontalDirectionalBlock.FACING,
StairBlock.FACING, StairBlock.HALF, StairBlock.SHAPE,
PipeBlock.NORTH, PipeBlock.EAST, PipeBlock.SOUTH, PipeBlock.WEST, PipeBlock.UP,
TrapDoorBlock.OPEN, TrapDoorBlock.HALF
);
private boolean sameBlockstate(BlockState first, BlockState second) {
private static boolean sameBlockstate(BlockState first, BlockState second) {
if (first.getBlock() != second.getBlock()) {
return false;
}
@@ -1030,7 +1054,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
ImmutableMap<Property<?>, Comparable<?>> map2 = second.getValues();
for (Property<?> prop : map1.keySet()) {
if (map1.get(prop) != map2.get(prop)
&& !(ignoreDirection && orientationProps.contains(prop))
&& !(ignoreDirection && ORIENTATION_PROPS.contains(prop))
&& !ignoredProps.contains(prop.getName())) {
return false;
}
@@ -1038,7 +1062,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return true;
}
private boolean containsBlockState(Collection<BlockState> states, BlockState state) {
private static boolean containsBlockState(Collection<BlockState> states, BlockState state) {
for (BlockState testee : states) {
if (sameBlockstate(testee, state)) {
return true;
@@ -1047,7 +1071,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return false;
}
private boolean valid(BlockState current, BlockState desired, boolean itemVerify) {
private static boolean valid(BlockState current, BlockState desired, boolean itemVerify) {
if (desired == null) {
return true;
}
@@ -1066,9 +1090,6 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
if (!(current.getBlock() instanceof AirBlock) && Baritone.settings().buildIgnoreExisting.value && !itemVerify) {
return true;
}
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;
}
@@ -1112,12 +1133,12 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return COST_INF;
}
BlockState sch = getSchematic(x, y, z, current);
if (sch != null && !Baritone.settings().buildSkipBlocks.value.contains(sch.getBlock())) {
if (sch != null) {
// TODO this can return true even when allowPlace is off.... is that an issue?
if (sch.getBlock() instanceof AirBlock) {
// we want this to be air, but they're asking if they can place here
// this won't be a schematic block, this will be a throwaway
return placeBlockCost * 2; // we're going to have to break it eventually
return placeBlockCost * Baritone.settings().placeIncorrectBlockPenaltyMultiplier.value; // we're going to have to break it eventually
}
if (placeable.contains(sch)) {
return 0; // thats right we gonna make it FREE to place a block where it should go in a structure
@@ -1130,7 +1151,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
}
// we want it to be something that we don't have
// even more of a pain to place something wrong
return placeBlockCost * 3;
return placeBlockCost * 1.5 * Baritone.settings().placeIncorrectBlockPenaltyMultiplier.value;
} else {
if (hasThrowaway) {
return placeBlockCost;
@@ -1146,7 +1167,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return COST_INF;
}
BlockState sch = getSchematic(x, y, z, current);
if (sch != null && !Baritone.settings().buildSkipBlocks.value.contains(sch.getBlock())) {
if (sch != null) {
if (sch.getBlock() instanceof AirBlock) {
// it should be air
// regardless of current contents, we can break it

View File

@@ -114,7 +114,7 @@ public final class CustomGoalProcess extends BaritoneProcessHelper implements IC
}
return new PathingCommand(this.goal, PathingCommandType.SET_GOAL_AND_PATH);
default:
throw new IllegalStateException();
throw new IllegalStateException("Unexpected state " + this.state);
}
}

View File

@@ -84,10 +84,10 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro
baritone.getGameEventHandler().registerEventListener(this);
}
public static <T extends IElytraProcess> T create(final Baritone baritone) {
return (T) (NetherPathfinderContext.isSupported()
public static IElytraProcess create(final Baritone baritone) {
return NetherPathfinderContext.isSupported()
? new ElytraProcess(baritone)
: new NullElytraProcess(baritone));
: new NullElytraProcess(baritone);
}
@Override

View File

@@ -118,7 +118,9 @@ public final class ExploreProcess extends BaritoneProcessHelper implements IExpl
int dz = (mult * 2 - 1) * zval; // dz can be either -zval or zval
int trueDist = Math.abs(dx) + Math.abs(dz);
if (trueDist != dist) {
throw new IllegalStateException();
throw new IllegalStateException(String.format(
"Offset %s %s has distance %s, expected %s",
dx, dz, trueDist, dist));
}
switch (filter.isAlreadyExplored(chunkX + dx, chunkZ + dz)) {
case UNKNOWN:

View File

@@ -42,6 +42,7 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.AirBlock;
import net.minecraft.world.level.block.BambooStalkBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.BonemealableBlock;
@@ -95,6 +96,7 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro
Items.NETHER_WART,
Items.COCOA_BEANS,
Blocks.SUGAR_CANE.asItem(),
Blocks.BAMBOO.asItem(),
Blocks.CACTUS.asItem()
);
@@ -137,6 +139,15 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro
return true;
}
},
BAMBOO(Blocks.BAMBOO, null) {
@Override
public boolean readyToHarvest(Level world, BlockPos pos, BlockState state) {
if (Baritone.settings().replantCrops.value) {
return world.getBlockState(pos.below()).getBlock() instanceof BambooStalkBlock;
}
return true;
}
},
CACTUS(Blocks.CACTUS, null) {
@Override
public boolean readyToHarvest(Level world, BlockPos pos, BlockState state) {
@@ -191,20 +202,20 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro
@Override
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
ArrayList<Block> scan = new ArrayList<>();
for (Harvest harvest : Harvest.values()) {
scan.add(harvest.block);
}
if (Baritone.settings().replantCrops.value) {
scan.add(Blocks.FARMLAND);
scan.add(Blocks.JUNGLE_LOG);
if (Baritone.settings().replantNetherWart.value) {
scan.add(Blocks.SOUL_SAND);
}
}
if (Baritone.settings().mineGoalUpdateInterval.value != 0 && tickCount++ % Baritone.settings().mineGoalUpdateInterval.value == 0) {
Baritone.getExecutor().execute(() -> locations = BaritoneAPI.getProvider().getWorldScanner().scanChunkRadius(ctx, scan, 256, 10, 10));
ArrayList<Block> scan = new ArrayList<>();
for (Harvest harvest : Harvest.values()) {
scan.add(harvest.block);
}
if (Baritone.settings().replantCrops.value) {
scan.add(Blocks.FARMLAND);
scan.add(Blocks.JUNGLE_LOG);
if (Baritone.settings().replantNetherWart.value) {
scan.add(Blocks.SOUL_SAND);
}
}
Baritone.getExecutor().execute(() -> locations = BaritoneAPI.getProvider().getWorldScanner().scanChunkRadius(ctx, scan, Baritone.settings().farmMaxScanSize.value, 10, 10));
}
if (locations == null) {
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
@@ -256,7 +267,12 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro
}
baritone.getInputOverrideHandler().clearAllKeys();
BetterBlockPos playerPos = ctx.playerFeet();
double blockReachDistance = ctx.playerController().getBlockReachDistance();
for (BlockPos pos : toBreak) {
if (playerPos.distSqr(pos) > blockReachDistance * blockReachDistance) {
continue;
}
Optional<Rotation> rot = RotationUtils.reachable(ctx, pos);
if (rot.isPresent() && isSafeToCancel) {
baritone.getLookBehavior().updateTarget(rot.get(), true);
@@ -270,10 +286,13 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro
ArrayList<BlockPos> both = new ArrayList<>(openFarmland);
both.addAll(openSoulsand);
for (BlockPos pos : both) {
if (playerPos.distSqr(pos) > blockReachDistance * blockReachDistance) {
continue;
}
boolean soulsand = openSoulsand.contains(pos);
Optional<Rotation> rot = RotationUtils.reachableOffset(ctx, pos, new Vec3(pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5), ctx.playerController().getBlockReachDistance(), false);
Optional<Rotation> rot = RotationUtils.reachableOffset(ctx, pos, new Vec3(pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5), blockReachDistance, false);
if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, soulsand ? this::isNetherWart : this::isPlantable)) {
HitResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot.get(), ctx.playerController().getBlockReachDistance());
HitResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot.get(), blockReachDistance);
if (result instanceof BlockHitResult && ((BlockHitResult) result).getDirection() == Direction.UP) {
baritone.getLookBehavior().updateTarget(rot.get(), true);
if (ctx.isLookingAt(pos)) {
@@ -284,14 +303,17 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro
}
}
for (BlockPos pos : openLog) {
if (playerPos.distSqr(pos) > blockReachDistance * blockReachDistance) {
continue;
}
for (Direction dir : Direction.Plane.HORIZONTAL) {
if (!(ctx.world().getBlockState(pos.relative(dir)).getBlock() instanceof AirBlock)) {
continue;
}
Vec3 faceCenter = Vec3.atCenterOf(pos).add(Vec3.atLowerCornerOf(dir.getNormal()).scale(0.5));
Optional<Rotation> rot = RotationUtils.reachableOffset(ctx, pos, faceCenter, ctx.playerController().getBlockReachDistance(), false);
Optional<Rotation> rot = RotationUtils.reachableOffset(ctx, pos, faceCenter, blockReachDistance, false);
if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, this::isCocoa)) {
HitResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot.get(), ctx.playerController().getBlockReachDistance());
HitResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot.get(), blockReachDistance);
if (result instanceof BlockHitResult && ((BlockHitResult) result).getDirection() == dir) {
baritone.getLookBehavior().updateTarget(rot.get(), true);
if (ctx.isLookingAt(pos)) {
@@ -303,6 +325,9 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro
}
}
for (BlockPos pos : bonemealable) {
if (playerPos.distSqr(pos) > blockReachDistance * blockReachDistance) {
continue;
}
Optional<Rotation> rot = RotationUtils.reachable(ctx, pos);
if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, this::isBoneMeal)) {
baritone.getLookBehavior().updateTarget(rot.get(), true);
@@ -359,6 +384,14 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro
}
}
}
if (goalz.isEmpty()) {
logDirect("Farm failed");
if (Baritone.settings().notificationOnFarmFail.value) {
logNotification("Farm failed", true);
}
onLostControl();
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
}
return new PathingCommand(new GoalComposite(goalz.toArray(new Goal[0])), PathingCommandType.SET_GOAL_AND_PATH);
}

View File

@@ -19,6 +19,7 @@ package baritone.process;
import baritone.Baritone;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalBlock;
import baritone.api.pathing.goals.GoalComposite;
import baritone.api.pathing.goals.GoalNear;
import baritone.api.pathing.goals.GoalXZ;
@@ -27,11 +28,14 @@ import baritone.api.process.PathingCommand;
import baritone.api.process.PathingCommandType;
import baritone.api.utils.BetterBlockPos;
import baritone.utils.BaritoneProcessHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.ItemStack;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity;
/**
* Follow an entity
@@ -42,6 +46,7 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
private Predicate<Entity> filter;
private List<Entity> cache;
private boolean into; // walk straight into the target, regardless of settings
public FollowProcess(Baritone baritone) {
super(baritone);
@@ -56,12 +61,15 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
private Goal towards(Entity following) {
BlockPos pos;
if (Baritone.settings().followOffsetDistance.value == 0) {
if (Baritone.settings().followOffsetDistance.value == 0 || into) {
pos = following.blockPosition();
} else {
GoalXZ g = GoalXZ.fromDirection(following.position(), Baritone.settings().followOffsetDirection.value, Baritone.settings().followOffsetDistance.value);
pos = new BetterBlockPos(g.getX(), following.position().y, g.getZ());
}
if (into) {
return new GoalBlock(pos);
}
return new GoalNear(pos, Baritone.settings().followRadius.value);
}
@@ -76,6 +84,10 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
if (entity.equals(ctx.player())) {
return false;
}
int maxDist = Baritone.settings().followTargetMaxDistance.value;
if (maxDist != 0 && entity.distanceToSqr(ctx.player()) > maxDist * maxDist) {
return false;
}
return ctx.entitiesStream().anyMatch(entity::equals);
}
@@ -110,6 +122,13 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
@Override
public void follow(Predicate<Entity> filter) {
this.filter = filter;
this.into = false;
}
@Override
public void pickup(Predicate<ItemStack> filter) {
this.filter = e -> e instanceof ItemEntity && filter.test(((ItemEntity) e).getItem());
this.into = true;
}
@Override

View File

@@ -53,8 +53,6 @@ import static baritone.api.pathing.movement.ActionCosts.COST_INF;
*/
public final class MineProcess extends BaritoneProcessHelper implements IMineProcess {
private static final int ORE_LOCATIONS_COUNT = 64;
private BlockOptionalMetaLookup filter;
private List<BlockPos> knownOreLocations;
private List<BlockPos> blacklist; // inaccessible
@@ -79,7 +77,6 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
int curr = ctx.player().getInventory().items.stream()
.filter(stack -> filter.has(stack))
.mapToInt(ItemStack::getCount).sum();
System.out.println("Currently have " + curr + " valid items");
if (curr >= desiredQuantity) {
logDirect("Have " + curr + " valid items");
cancel();
@@ -121,7 +118,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
.filter(pos -> pos.getX() == ctx.playerFeet().getX() && pos.getZ() == ctx.playerFeet().getZ())
.filter(pos -> pos.getY() >= ctx.playerFeet().getY())
.filter(pos -> !(BlockStateInterface.get(ctx, pos).getBlock() instanceof AirBlock)) // after breaking a block, it takes mineGoalUpdateInterval ticks for it to actually update this list =(
.min(Comparator.comparingDouble(ctx.playerFeet()::distSqr));
.min(Comparator.comparingDouble(ctx.playerFeet().above()::distSqr));
baritone.getInputOverrideHandler().clearAllKeys();
if (shaft.isPresent() && ctx.player().isOnGround()) {
BlockPos pos = shaft.get();
@@ -186,7 +183,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
List<BlockPos> locs = knownOreLocations;
if (!locs.isEmpty()) {
CalculationContext context = new CalculationContext(baritone);
List<BlockPos> locs2 = prune(context, new ArrayList<>(locs), filter, ORE_LOCATIONS_COUNT, blacklist, droppedItemsScan());
List<BlockPos> locs2 = prune(context, new ArrayList<>(locs), filter, Baritone.settings().mineMaxOreLocationsCount.value, blacklist, droppedItemsScan());
// can't reassign locs, gotta make a new var locs2, because we use it in a lambda right here, and variables you use in a lambda must be effectively final
Goal goal = new GoalComposite(locs2.stream().map(loc -> coalesce(loc, locs2, context)).toArray(Goal[]::new));
knownOreLocations = locs2;
@@ -235,7 +232,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
return;
}
List<BlockPos> dropped = droppedItemsScan();
List<BlockPos> locs = searchWorld(context, filter, ORE_LOCATIONS_COUNT, already, blacklist, dropped);
List<BlockPos> locs = searchWorld(context, filter, Baritone.settings().mineMaxOreLocationsCount.value, already, blacklist, dropped);
locs.addAll(dropped);
if (locs.isEmpty() && !Baritone.settings().exploreForBlocks.value) {
logDirect("No locations for " + filter + " known, cancelling");
@@ -425,7 +422,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
}
}
}
knownOreLocations = prune(new CalculationContext(baritone), knownOreLocations, filter, ORE_LOCATIONS_COUNT, blacklist, dropped);
knownOreLocations = prune(new CalculationContext(baritone), knownOreLocations, filter, Baritone.settings().mineMaxOreLocationsCount.value, blacklist, dropped);
return true;
}
@@ -488,7 +485,11 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
public static boolean plausibleToBreak(CalculationContext ctx, BlockPos pos) {
if (MovementHelper.getMiningDurationTicks(ctx, pos.getX(), pos.getY(), pos.getZ(), ctx.bsi.get0(pos), true) >= COST_INF) {
BlockState state = ctx.bsi.get0(pos);
if (MovementHelper.getMiningDurationTicks(ctx, pos.getX(), pos.getY(), pos.getZ(), state, true) >= COST_INF) {
return false;
}
if (MovementHelper.avoidBreaking(ctx.bsi, pos.getX(), pos.getY(), pos.getZ(), state)) {
return false;
}

View File

@@ -17,7 +17,9 @@
package baritone.utils;
import baritone.api.BaritoneAPI;
import baritone.api.utils.IPlayerContext;
import baritone.utils.accessor.IPlayerControllerMP;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
@@ -27,9 +29,12 @@ import net.minecraft.world.phys.HitResult;
* @since 8/25/2018
*/
public final class BlockBreakHelper {
// base ticks between block breaks caused by tick logic
private static final int BASE_BREAK_DELAY = 1;
private final IPlayerContext ctx;
private boolean didBreakLastTick;
private boolean wasHitting;
private int breakDelayTimer = 0;
BlockBreakHelper(IPlayerContext ctx) {
this.ctx = ctx;
@@ -37,38 +42,46 @@ public final class BlockBreakHelper {
public void stopBreakingBlock() {
// The player controller will never be null, but the player can be
if (ctx.player() != null && didBreakLastTick) {
if (!ctx.playerController().hasBrokenBlock()) {
// insane bypass to check breaking succeeded
ctx.playerController().setHittingBlock(true);
}
if (ctx.player() != null && wasHitting) {
ctx.playerController().setHittingBlock(false);
ctx.playerController().resetBlockRemoving();
didBreakLastTick = false;
wasHitting = false;
}
}
public void tick(boolean isLeftClick) {
if (breakDelayTimer > 0) {
breakDelayTimer--;
return;
}
HitResult trace = ctx.objectMouseOver();
boolean isBlockTrace = trace != null && trace.getType() == HitResult.Type.BLOCK;
if (isLeftClick && isBlockTrace) {
if (!didBreakLastTick) {
ctx.playerController().setHittingBlock(wasHitting);
if (ctx.playerController().hasBrokenBlock()) {
ctx.playerController().syncHeldItem();
ctx.playerController().clickBlock(((BlockHitResult) trace).getBlockPos(), ((BlockHitResult) trace).getDirection());
ctx.player().swing(InteractionHand.MAIN_HAND);
} else {
if (ctx.playerController().onPlayerDamageBlock(((BlockHitResult) trace).getBlockPos(), ((BlockHitResult) trace).getDirection())) {
ctx.player().swing(InteractionHand.MAIN_HAND);
}
if (ctx.playerController().hasBrokenBlock()) { // block broken this tick
// break delay timer only applies for multi-tick block breaks like vanilla
breakDelayTimer = BaritoneAPI.getSettings().blockBreakSpeed.value - BASE_BREAK_DELAY;
// must reset controller's destroy delay to prevent the client from delaying itself unnecessarily
((IPlayerControllerMP) ctx.minecraft().gameMode).setDestroyDelay(0);
}
}
// Attempt to break the block
if (ctx.playerController().onPlayerDamageBlock(((BlockHitResult) trace).getBlockPos(), ((BlockHitResult) trace).getDirection())) {
ctx.player().swing(InteractionHand.MAIN_HAND);
}
// if true, we're breaking a block. if false, we broke the block this tick
wasHitting = !ctx.playerController().hasBrokenBlock();
// this value will be reset by the MC client handling mouse keys
// since we're not spoofing the click keybind to the client, the client will stop the break if isDestroyingBlock is true
// we store and restore this value on the next tick to determine if we're breaking a block
ctx.playerController().setHittingBlock(false);
didBreakLastTick = true;
} else if (didBreakLastTick) {
stopBreakingBlock();
didBreakLastTick = false;
} else {
wasHitting = false;
}
}
}

View File

@@ -25,6 +25,8 @@ import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
public class BlockPlaceHelper {
// base ticks between places caused by tick logic
private static final int BASE_PLACE_DELAY = 1;
private final IPlayerContext ctx;
private int rightClickTimer;
@@ -42,7 +44,7 @@ public class BlockPlaceHelper {
if (!rightClickRequested || ctx.player().isHandsBusy() || mouseOver == null || mouseOver.getType() != HitResult.Type.BLOCK) {
return;
}
rightClickTimer = Baritone.settings().rightClickSpeed.value;
rightClickTimer = Baritone.settings().rightClickSpeed.value - BASE_PLACE_DELAY;
for (InteractionHand hand : InteractionHand.values()) {
if (ctx.playerController().processRightClickBlock(ctx.player(), ctx.world(), hand, (BlockHitResult) mouseOver) == InteractionResult.SUCCESS) {
ctx.player().swing(hand);

View File

@@ -70,7 +70,7 @@ public class BlockStateInterface {
}
this.useTheRealWorld = !Baritone.settings().pathThroughCachedOnly.value;
if (!ctx.minecraft().isSameThread()) {
throw new IllegalStateException();
throw new IllegalStateException("BlockStateInterface must be constructed on the main thread");
}
this.isPassableBlockPos = new BlockPos.MutableBlockPos();
this.access = new BlockStateInterfaceAccessWrapper(this);

View File

@@ -56,12 +56,12 @@ public final class BlockStateInterfaceAccessWrapper implements BlockGetter {
@Override
public int getHeight() {
return 255;
return bsi.world.getHeight();
}
@Override
public int getMinBuildHeight() {
return 0;
return bsi.world.getMinBuildHeight();
}
}

View File

@@ -73,13 +73,11 @@ public class GuiClick extends Screen implements Helper {
Vec3 far = toWorld(mx, my, 1); // "Use 0.945 that's what stack overflow says" - leijurv
if (near != null && far != null) {
///
Vec3 viewerPos = new Vec3(PathRenderer.posX(), PathRenderer.posY(), PathRenderer.posZ());
LocalPlayer player = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().player();
HitResult result = player.level.clip(new ClipContext(near.add(viewerPos), far.add(viewerPos), ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player));
if (result != null && result.getType() == HitResult.Type.BLOCK) {
currentMouseOver = ((BlockHitResult) result).getBlockPos();
System.out.println("currentMouseOver = " + currentMouseOver);
}
}
}

View File

@@ -68,7 +68,7 @@ public class PathingControlManager implements IPathingControlManager {
for (IBaritoneProcess proc : processes) {
proc.onLostControl();
if (proc.isActive() && !proc.isTemporary()) { // it's okay only for a temporary thing (like combat pause) to maintain control even if you say to cancel
throw new IllegalStateException(proc.displayName());
throw new IllegalStateException(proc.displayName() + " stayed active after being cancelled");
}
}
}
@@ -121,7 +121,7 @@ public class PathingControlManager implements IPathingControlManager {
}
break;
default:
throw new IllegalStateException();
throw new IllegalStateException("Unexpected command type " + command.commandType);
}
}

View File

@@ -177,7 +177,13 @@ public class ToolSet {
* @return how long it would take in ticks
*/
public static double calculateSpeedVsBlock(ItemStack item, BlockState state) {
float hardness = state.getDestroySpeed(null, null);
float hardness;
try {
hardness = state.getDestroySpeed(null, null);
} catch (NullPointerException npe) {
// can't easily determine the hardness so treat it as unbreakable
return -1;
}
if (hardness < 0) {
return -1;
}

View File

@@ -23,7 +23,11 @@ public interface IPlayerControllerMP {
void setIsHittingBlock(boolean isHittingBlock);
boolean isHittingBlock();
BlockPos getCurrentBlock();
void callSyncCurrentPlayItem();
void setDestroyDelay(int destroyDelay);
}

View File

@@ -20,7 +20,6 @@ package baritone.utils.player;
import baritone.api.utils.IPlayerController;
import baritone.utils.accessor.IPlayerControllerMP;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@@ -54,7 +53,7 @@ public final class BaritonePlayerController implements IPlayerController {
@Override
public boolean hasBrokenBlock() {
return ((IPlayerControllerMP) mc.gameMode).getCurrentBlock().getY() == -1;
return !((IPlayerControllerMP) mc.gameMode).isHittingBlock();
}
@Override

View File

@@ -41,6 +41,7 @@ public class MapArtSchematic extends MaskSchematic {
private static int[][] generateHeightMap(IStaticSchematic schematic) {
int[][] heightMap = new int[schematic.widthX()][schematic.lengthZ()];
int missingColumns = 0;
for (int x = 0; x < schematic.widthX(); x++) {
for (int z = 0; z < schematic.lengthZ(); z++) {
BlockState[] column = schematic.getColumn(x, z);
@@ -48,12 +49,14 @@ public class MapArtSchematic extends MaskSchematic {
if (lowestBlockY.isPresent()) {
heightMap[x][z] = lowestBlockY.getAsInt();
} else {
System.out.println("Column " + x + "," + z + " has no blocks, but it's apparently map art? wtf");
System.out.println("Letting it be whatever");
heightMap[x][z] = 256;
missingColumns++;
heightMap[x][z] = Integer.MAX_VALUE;
}
}
}
if (missingColumns != 0) {
System.out.println(missingColumns + " columns had no block despite being in a map art, letting them be whatever");
}
return heightMap;
}

View File

@@ -24,6 +24,7 @@ import baritone.utils.schematic.format.DefaultSchematicFormats;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
/**
@@ -48,4 +49,9 @@ public enum SchematicSystem implements ISchematicSystem {
public Optional<ISchematicFormat> getByFile(File file) {
return this.registry.stream().filter(format -> format.isFileType(file)).findFirst();
}
@Override
public List<String> getFileExtensions() {
return this.registry.stream().map(ISchematicFormat::getFileExtensions).flatMap(List::stream).toList();
}
}

View File

@@ -32,6 +32,16 @@ public class StaticSchematic extends AbstractSchematic implements IStaticSchemat
protected BlockState[][][] states;
public StaticSchematic() {}
public StaticSchematic(BlockState[][][] states) {
this.states = states;
boolean empty = states.length == 0 || states[0].length == 0 || states[0][0].length == 0;
this.x = empty ? 0 : states.length;
this.z = empty ? 0 : states[0].length;
this.y = empty ? 0 : states[0][0].length;
}
@Override
public BlockState desiredState(int x, int y, int z, BlockState current, List<BlockState> approxPlaceable) {
return this.states[x][z][y];

View File

@@ -22,13 +22,15 @@ 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.CompoundTag;
import net.minecraft.nbt.NbtIo;
import org.apache.commons.io.FilenameUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtIo;
import java.util.Collections;
import java.util.List;
/**
* Default implementations of {@link ISchematicFormat}
@@ -81,7 +83,7 @@ public enum DefaultSchematicFormats implements ISchematicFormat {
case 5: //1.13-1.17
throw new UnsupportedOperationException("This litematic Version is too old.");
case 6: //1.18+
return new LitematicaSchematic(nbt, false);
return new LitematicaSchematic(nbt);
default:
throw new UnsupportedOperationException("Unsuported Version of a Litematica Schematic");
}
@@ -98,4 +100,9 @@ public enum DefaultSchematicFormats implements ISchematicFormat {
public boolean isFileType(File file) {
return this.extension.equalsIgnoreCase(FilenameUtils.getExtension(file.getAbsolutePath()));
}
@Override
public List<String> getFileExtensions() {
return Collections.singletonList(this.extension);
}
}

View File

@@ -17,8 +17,9 @@
package baritone.utils.schematic.format.defaults;
import baritone.api.schematic.CompositeSchematic;
import baritone.api.schematic.IStaticSchematic;
import baritone.utils.schematic.StaticSchematic;
import net.minecraft.core.Registry;
import net.minecraft.core.Vec3i;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
@@ -30,6 +31,7 @@ import net.minecraft.world.level.block.state.properties.Property;
import org.apache.commons.lang3.Validate;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.Optional;
/**
@@ -39,35 +41,24 @@ import java.util.Optional;
* @author rycbar
* @since 22.09.2022
*/
public final class LitematicaSchematic extends StaticSchematic {
private final Vec3i offsetMinCorner;
private final CompoundTag nbt;
public final class LitematicaSchematic extends CompositeSchematic implements IStaticSchematic {
/**
* @param nbtTagCompound a decompressed file stream aka nbt data.
* @param rotated if the schematic is rotated by 90°.
*/
public LitematicaSchematic(CompoundTag nbtTagCompound, boolean rotated) {
this.nbt = nbtTagCompound;
this.offsetMinCorner = new Vec3i(getMinOfSchematic("x"), getMinOfSchematic("y"), getMinOfSchematic("z"));
this.y = Math.abs(nbt.getCompound("Metadata").getCompound("EnclosingSize").getInt("y"));
if (rotated) {
this.x = Math.abs(nbt.getCompound("Metadata").getCompound("EnclosingSize").getInt("z"));
this.z = Math.abs(nbt.getCompound("Metadata").getCompound("EnclosingSize").getInt("x"));
} else {
this.x = Math.abs(nbt.getCompound("Metadata").getCompound("EnclosingSize").getInt("x"));
this.z = Math.abs(nbt.getCompound("Metadata").getCompound("EnclosingSize").getInt("z"));
}
this.states = new BlockState[this.x][this.z][this.y];
fillInSchematic();
public LitematicaSchematic(CompoundTag nbt) {
super(0, 0, 0);
fillInSchematic(nbt);
}
/**
* @return Array of subregion names.
* @return Array of subregion tags.
*/
private static String[] getRegions(CompoundTag nbt) {
return nbt.getCompound("Regions").getAllKeys().toArray(new String[0]);
private static CompoundTag[] getRegions(CompoundTag nbt) {
return nbt.getCompound("Regions").getAllKeys().stream()
.map(nbt.getCompound("Regions")::getCompound)
.toArray(CompoundTag[]::new);
}
/**
@@ -76,14 +67,10 @@ public final class LitematicaSchematic extends StaticSchematic {
* @param s axis that should be read.
* @return the lower coord of the requested axis.
*/
private static int getMinOfSubregion(CompoundTag nbt, String subReg, String s) {
int a = nbt.getCompound("Regions").getCompound(subReg).getCompound("Position").getInt(s);
int b = nbt.getCompound("Regions").getCompound(subReg).getCompound("Size").getInt(s);
if (b < 0) {
b++;
}
return Math.min(a, a + b);
private static int getMinOfSubregion(CompoundTag subReg, String s) {
int a = subReg.getCompound("Position").getInt(s);
int b = subReg.getCompound("Size").getInt(s);
return Math.min(a, a + b + 1);
}
/**
@@ -110,7 +97,7 @@ public final class LitematicaSchematic extends StaticSchematic {
private static BlockState getBlockState(Block block, CompoundTag properties) {
BlockState blockState = block.defaultBlockState();
for (Object key : properties.getAllKeys().toArray()) {
for (Object key : properties.getAllKeys()) {
Property<?> property = block.getStateDefinition().getProperty((String) key);
String propertyValue = properties.getString((String) key);
if (property != null) {
@@ -146,43 +133,19 @@ public final class LitematicaSchematic extends StaticSchematic {
*
* @return the volume of the subregion.
*/
private static long getVolume(CompoundTag nbt, String subReg) {
return Math.abs(
nbt.getCompound("Regions").getCompound(subReg).getCompound("Size").getInt("x") *
nbt.getCompound("Regions").getCompound(subReg).getCompound("Size").getInt("y") *
nbt.getCompound("Regions").getCompound(subReg).getCompound("Size").getInt("z"));
}
/**
* @return array of Long values.
*/
private static long[] getBlockStates(CompoundTag nbt, String subReg) {
return nbt.getCompound("Regions").getCompound(subReg).getLongArray("BlockStates");
}
/**
* 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(CompoundTag nbt, String subReg, int x, int y, int z) {
return x >= 0 && y >= 0 && z >= 0 &&
x < Math.abs(nbt.getCompound("Regions").getCompound(subReg).getCompound("Size").getInt("x")) &&
y < Math.abs(nbt.getCompound("Regions").getCompound(subReg).getCompound("Size").getInt("y")) &&
z < Math.abs(nbt.getCompound("Regions").getCompound(subReg).getCompound("Size").getInt("z"));
private static long getVolume(CompoundTag subReg) {
CompoundTag size = subReg.getCompound("Size");
return Math.abs(size.getInt("x") * size.getInt("y") * size.getInt("z"));
}
/**
* @param s axis.
* @return the lowest coordinate of that axis of the schematic.
*/
private int getMinOfSchematic(String s) {
private static int getMinOfSchematic(CompoundTag nbt, String s) {
int n = Integer.MAX_VALUE;
for (String subReg : getRegions(nbt)) {
n = Math.min(n, getMinOfSubregion(nbt, subReg, s));
for (CompoundTag subReg : getRegions(nbt)) {
n = Math.min(n, getMinOfSubregion(subReg, s));
}
return n;
}
@@ -190,18 +153,18 @@ public final class LitematicaSchematic extends StaticSchematic {
/**
* reads the file data.
*/
private void fillInSchematic() {
for (String subReg : getRegions(nbt)) {
ListTag usedBlockTypes = nbt.getCompound("Regions").getCompound(subReg).getList("BlockStatePalette", 10);
private void fillInSchematic(CompoundTag nbt) {
Vec3i offsetMinCorner = new Vec3i(getMinOfSchematic(nbt, "x"), getMinOfSchematic(nbt, "y"), getMinOfSchematic(nbt, "z"));
for (CompoundTag subReg : getRegions(nbt)) {
ListTag usedBlockTypes = subReg.getList("BlockStatePalette", 10);
BlockState[] blockList = getBlockList(usedBlockTypes);
int bitsPerBlock = getBitsPerBlock(usedBlockTypes.size());
long regionVolume = getVolume(nbt, subReg);
long[] blockStateArray = getBlockStates(nbt, subReg);
long regionVolume = getVolume(subReg);
long[] blockStateArray = subReg.getLongArray("BlockStates");
LitematicaBitArray bitArray = new LitematicaBitArray(bitsPerBlock, regionVolume, blockStateArray);
writeSubregionIntoSchematic(nbt, subReg, blockList, bitArray);
writeSubregionIntoSchematic(subReg, offsetMinCorner, blockList, bitArray);
}
}
@@ -211,65 +174,30 @@ public final class LitematicaSchematic extends StaticSchematic {
* @param blockList list with the different block types used in the schematic.
* @param bitArray bit array that holds the placement pattern.
*/
private void writeSubregionIntoSchematic(CompoundTag nbt, String subReg, BlockState[] blockList, LitematicaBitArray bitArray) {
Vec3i offsetSubregion = new Vec3i(getMinOfSubregion(nbt, subReg, "x"), getMinOfSubregion(nbt, subReg, "y"), getMinOfSubregion(nbt, subReg, "z"));
private void writeSubregionIntoSchematic(CompoundTag subReg, Vec3i offsetMinCorner, BlockState[] blockList, LitematicaBitArray bitArray) {
int offsetX = getMinOfSubregion(subReg, "x") - offsetMinCorner.getX();
int offsetY = getMinOfSubregion(subReg, "y") - offsetMinCorner.getY();
int offsetZ = getMinOfSubregion(subReg, "z") - offsetMinCorner.getZ();
CompoundTag size = subReg.getCompound("Size");
int sizeX = Math.abs(size.getInt("x"));
int sizeY = Math.abs(size.getInt("y"));
int sizeZ = Math.abs(size.getInt("z"));
BlockState[][][] states = new BlockState[sizeX][sizeZ][sizeY];
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++;
}
for (int y = 0; y < sizeY; y++) {
for (int z = 0; z < sizeZ; z++) {
for (int x = 0; x < sizeX; x++) {
states[x][z][y] = blockList[bitArray.getAt(index)];
index++;
}
}
}
this.put(new StaticSchematic(states), offsetX, offsetY, offsetZ);
}
/**
* @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, BlockState 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);
@Override
public BlockState getDirect(int x, int y, int z) {
return desiredState(x, y, z, null, Collections.emptyList());
}
/**

View File

@@ -17,15 +17,26 @@
package baritone.utils.schematic.litematica;
import baritone.utils.schematic.format.defaults.LitematicaSchematic;
import baritone.api.schematic.CompositeSchematic;
import baritone.api.schematic.IStaticSchematic;
import baritone.utils.schematic.StaticSchematic;
import fi.dy.masa.litematica.Litematica;
import fi.dy.masa.litematica.data.DataManager;
import fi.dy.masa.litematica.schematic.placement.SchematicPlacement;
import fi.dy.masa.litematica.schematic.placement.SubRegionPlacement;
import fi.dy.masa.litematica.world.SchematicWorldHandler;
import fi.dy.masa.litematica.world.WorldSchematic;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Vec3i;
import net.minecraft.util.Tuple;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Mirror;
import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.block.state.BlockState;
import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* Helper class that provides access or processes data related to Litmatica schematics.
@@ -48,168 +59,98 @@ public final class LitematicaHelper {
}
/**
* @return if there are loaded schematics.
* @return if {@code i} is a valid placement index
*/
public static boolean hasLoadedSchematic() {
return DataManager.getSchematicPlacementManager().getAllSchematicsPlacements().size() > 0;
public static boolean hasLoadedSchematic(int i) {
return 0 <= i && i < DataManager.getSchematicPlacementManager().getAllSchematicsPlacements().size();
}
/**
* @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();
private static SchematicPlacement getPlacement(int i) {
return DataManager.getSchematicPlacementManager().getAllSchematicsPlacements().get(i);
}
/**
* @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();
private static Vec3i transform(Vec3i in, Mirror mirror, Rotation rotation) {
int x = in.getX();
int z = in.getZ();
if (mirror == Mirror.LEFT_RIGHT) {
zOut = sizeZ - in.getZ();
z = -z;
} else if (mirror == Mirror.FRONT_BACK) {
xOut = sizeX - in.getX();
x = -x;
}
switch (rotation) {
case CLOCKWISE_90:
return new Vec3i(-z, in.getY(), x);
case CLOCKWISE_180:
return new Vec3i(-x, in.getY(), -z);
case COUNTERCLOCKWISE_90:
return new Vec3i(z, in.getY(), -x);
default:
return new Vec3i(x, in.getY(), z);
}
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.
* @param i index of the Schematic in the schematic placement list.
* @return The transformed schematic and the position of its minimum corner
*/
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);
}
public static Tuple<IStaticSchematic, Vec3i> getSchematic(int i) {
SchematicPlacement placement = getPlacement(i);
int minX = Integer.MAX_VALUE;
int minY = Integer.MAX_VALUE;
int minZ = Integer.MAX_VALUE;
HashMap<Vec3i, StaticSchematic> subRegions = new HashMap<>();
Level schematicWorld = SchematicWorldHandler.getSchematicWorld();
for (Map.Entry<String, SubRegionPlacement> entry : placement.getEnabledRelativeSubRegionPlacements().entrySet()) {
SubRegionPlacement subPlacement = entry.getValue();
Vec3i pos = transform(subPlacement.getPos(), placement.getMirror(), placement.getRotation());
Vec3i size = placement.getSchematic().getAreaSize(entry.getKey());
size = transform(size, placement.getMirror(), placement.getRotation());
size = transform(size, subPlacement.getMirror(), subPlacement.getRotation());
int mx = Math.min(size.getX() + 1, 0);
int my = Math.min(size.getY() + 1, 0);
int mz = Math.min(size.getZ() + 1, 0);
minX = Math.min(minX, pos.getX() + mx);
minY = Math.min(minY, pos.getY() + my);
minZ = Math.min(minZ, pos.getZ() + mz);
BlockPos origin = placement.getOrigin().offset(pos).offset(mx, my, mz);
BlockState[][][] states = new BlockState[Math.abs(size.getX())][Math.abs(size.getZ())][Math.abs(size.getY())];
for (int x = 0; x < states.length; x++) {
for (int z = 0; z < states[x].length; z++) {
for (int y = 0; y < states[x][z].length; y++) {
states[x][z][y] = schematicWorld.getBlockState(origin.offset(x, y, z));
}
BlockState state = schemIn.getDirect(xCounter, yCounter, zCounter);
try {
state = state.mirror(LitematicaHelper.getMirror(i)).rotate(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);
}
}
StaticSchematic schematic = new StaticSchematic(states);
subRegions.put(pos.offset(mx, my, mz), schematic);
}
return tempSchem;
LitematicaPlacementSchematic composite = new LitematicaPlacementSchematic(placement.getName());
for (Map.Entry<Vec3i, StaticSchematic> entry : subRegions.entrySet()) {
Vec3i pos = entry.getKey().offset(-minX, -minY, -minZ);
composite.put(entry.getValue(), pos.getX(), pos.getY(), pos.getZ());
}
return new Tuple<>(composite, placement.getOrigin().offset(minX, minY, minZ));
}
}
private static class LitematicaPlacementSchematic extends CompositeSchematic implements IStaticSchematic {
private final String name;
public LitematicaPlacementSchematic(String name) {
super(0, 0, 0);
this.name = name;
}
@Override
public BlockState getDirect(int x, int y, int z) {
if (inSchematic(x, y, z, null)) {
return desiredState(x, y, z, null, Collections.emptyList());
}
return null;
}
@Override
public String toString() {
return name;
}
}
}

View File

@@ -20,14 +20,8 @@ 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;
throw new LinkageError();
}
}

View File

@@ -0,0 +1,27 @@
/*
* 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;
import net.minecraft.core.BlockPos;
public class LitematicaSchematic {
public BlockPos getAreaSize(String name) {
throw new LinkageError();
}
}

View File

@@ -17,19 +17,35 @@
package fi.dy.masa.litematica.schematic.placement;
import com.google.common.collect.ImmutableMap;
import fi.dy.masa.litematica.schematic.LitematicaSchematic;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.Mirror;
import net.minecraft.world.level.block.Rotation;
public class SchematicPlacement extends SchematicPlacementUnloaded {
private Rotation rotation;
private Mirror mirror;
public class SchematicPlacement {
public String getName() {
throw new LinkageError();
}
public BlockPos getOrigin() {
throw new LinkageError();
}
public Rotation getRotation() {
return this.rotation;
throw new LinkageError();
}
public Mirror getMirror() {
return this.mirror;
throw new LinkageError();
}
public ImmutableMap<String, SubRegionPlacement> getEnabledRelativeSubRegionPlacements() {
throw new LinkageError();
}
public LitematicaSchematic getSchematic() {
throw new LinkageError();
}
}

View File

@@ -17,15 +17,13 @@
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;
throw new LinkageError();
}
}

View File

@@ -18,26 +18,20 @@
package fi.dy.masa.litematica.schematic.placement;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.Mirror;
import net.minecraft.world.level.block.Rotation;
import javax.annotation.Nullable;
import java.io.File;
public class SubRegionPlacement {
public class SchematicPlacementUnloaded {
protected String name = "?";
@Nullable
protected File schematicFile;
protected BlockPos origin = BlockPos.ZERO;
public String getName() {
return this.name;
public BlockPos getPos() {
throw new LinkageError();
}
@Nullable
public File getSchematicFile() {
return this.schematicFile;
public Rotation getRotation() {
throw new LinkageError();
}
public BlockPos getOrigin() {
return this.origin;
public Mirror getMirror() {
throw new LinkageError();
}
}

View File

@@ -0,0 +1,25 @@
/*
* 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.world;
public class SchematicWorldHandler {
public static WorldSchematic getSchematicWorld() {
throw new LinkageError();
}
}

View File

@@ -0,0 +1,27 @@
/*
* 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.world;
import net.minecraft.world.level.Level;
public abstract class WorldSchematic extends Level {
private WorldSchematic() {
super(null, null, null, null, null, false, false, 0, 0);
throw new LinkageError();
}
}

View File

@@ -26,7 +26,7 @@ plugins {
unimined.minecraft {
runs.client = {
mainClass = "net.minecraft.launchwrapper.Launch"
args.addAll(["--tweakClass", "baritone.launch.BaritoneTweaker"])
args.addAll(["--tweakClass", "baritone.launch.tweaker.BaritoneTweaker"])
}
}
@@ -38,14 +38,14 @@ configurations {
}
dependencies {
implementation "org.spongepowered:mixin:0.8.5"
implementation "org.spongepowered:mixin:${project.mixin_version}"
// for some reason mixin isn't including these...
implementation "org.ow2.asm:asm:9.3"
implementation "org.ow2.asm:asm-tree:9.3"
implementation "org.ow2.asm:asm-commons:9.3"
implementation "org.ow2.asm:asm-util:9.3"
implementation "org.ow2.asm:asm-analysis:9.3"
implementation "org.ow2.asm:asm:${project.asm_version}"
implementation "org.ow2.asm:asm-tree:${project.asm_version}"
implementation "org.ow2.asm:asm-commons:${project.asm_version}"
implementation "org.ow2.asm:asm-util:${project.asm_version}"
implementation "org.ow2.asm:asm-analysis:${project.asm_version}"
implementation 'com.github.ImpactDevelopment:SimpleTweaker:1.2'
@@ -95,8 +95,7 @@ jar {
}
task proguard(type: ProguardTask) {
url 'https://github.com/Guardsquare/proguard/releases/download/v7.2.1/proguard-7.2.1.zip'
extract 'proguard-7.2.1/lib/proguard.jar'
proguardVersion "7.2.1"
}
task createDist(type: CreateDistTask, dependsOn: proguard)

View File

@@ -15,7 +15,7 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch;
package baritone.launch.tweaker;
import io.github.impactdevelopment.simpletweaker.SimpleTweaker;
import net.minecraft.launchwrapper.Launch;