Compare commits

...

43 Commits

Author SHA1 Message Date
Leijurv
9d5db72806 v1.11.1 2024-11-20 01:10:40 -08:00
leijurv
b14c75804d Merge pull request #4536 from rfresh2/1.21.3
1.21.3
2024-11-05 21:37:50 -08:00
rfresh2
fd4fbf5df5 update forge and resolve rebase conflicts 2024-10-30 20:44:51 -07:00
rfresh2
7e8c8501a7 restore tool getMaterialCost intended functionality 2024-10-30 20:34:16 -07:00
rfresh2
55cb180755 1.21.3 2024-10-30 20:34:12 -07:00
leijurv
9eefcbc9b6 Merge pull request #4534 from ZacSharp/1.21.1-update
Merge 1.20.5 into 1.21.1
2024-10-30 02:04:49 -07:00
ZacSharp
52cfe5cf7e Merge branch '1.20.5' into 1.21.1 2024-10-23 01:12:52 +02:00
leijurv
b550b92b0a Merge pull request #4527 from ZacSharp/1.20.5-update
Merge 1.19.4 into 1.20.5
2024-10-22 15:53:06 -07:00
ZacSharp
28695031d7 Merge branch '1.19.4' into 1.20.5 2024-10-22 14:50:47 +02: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
50291089db Merge pull request #4520 from KKyleK/update-docker-java
Update Java version used by Docker
2024-10-15 16:04:42 -07: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
Kyle Koivuneva
5102d9164e Update Java version used by Docker
In 6b2fd5acee the java version used to build baritone
was bumped from 17 to 21, but the Docker build was not updated accordingly.
2024-10-15 21:58:23 +00: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
a231748b4e Merge pull request #4466 from rfresh2/1.21.1-compat
mark 1.21.1 as compatible
2024-08-22 11:04:21 -07:00
leijurv
800545f0b5 Merge pull request #4465 from ZacSharp/pr/1.20.6/selection/fixSelectionAABB
Fix selection box aabbs
2024-08-22 11:01:45 -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
rfresh2
960ff6ed98 mark 1.21.1 as compatible 2024-08-09 20:31:29 -07:00
ZacSharp
e682fc75a6 Fix selection box aabbs 2024-08-09 13:54:29 +02: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
48 changed files with 753 additions and 526 deletions

View File

@@ -5,7 +5,7 @@ ENV DEBIAN_FRONTEND noninteractive
RUN apt update -y
RUN apt install \
openjdk-17-jdk \
openjdk-21-jdk \
git \
--assume-yes

View File

@@ -78,11 +78,9 @@ allprojects {
}
dependencies {
compileOnly "org.spongepowered:mixin:0.8"
compileOnly "org.ow2.asm:asm:9.7"
// 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')
compileOnly "org.spongepowered:mixin:${project.mixin_version}"
compileOnly "org.ow2.asm:asm:${project.asm_version}"
implementation "dev.babbaj:nether-pathfinder:${project.nether_pathfinder_version}"
implementation 'com.google.code.findbugs:jsr305:3.0.2'

View File

@@ -25,6 +25,6 @@
"depends": {
"fabricloader": ">=0.14.22",
"minecraft": "1.21"
"minecraft": ["1.21.2","1.21.3"]
}
}

View File

@@ -35,6 +35,6 @@ A Minecraft pathfinder bot.
modId="minecraft"
mandatory=true
# This version range declares a minimum of the current minecraft version up to but not including the next major version
versionRange="[1.21]"
versionRange="[1.21.2, 1.21.3]"
ordering="NONE"
side="BOTH"

View File

@@ -2,18 +2,23 @@ org.gradle.jvmargs=-Xmx4G
available_loaders=fabric,forge,neoforge,tweaker
mod_version=1.11.0
mod_version=1.12.0
maven_group=baritone
archives_base_name=baritone
java_version=21
minecraft_version=1.21
minecraft_version=1.21.3
forge_version=51.0.16
forge_version=53.0.7
neoforge_version=20-beta
neoforge_version=6-beta
fabric_version=0.15.11
fabric_version=0.16.7
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.7

View File

@@ -26,7 +26,7 @@ archivesBaseName = archivesBaseName + "-neoforge"
unimined.minecraft {
neoForged {
neoForge {
loader project.neoforge_version
mixinConfig ["mixins.baritone.json"]
}

View File

@@ -35,6 +35,6 @@ A Minecraft pathfinder bot.
modId="minecraft"
type="required"
# This version range declares a minimum of the current minecraft version up to but not including the next major version
versionRange="[1.21]"
versionRange="[1.21.2,1.21.3]"
ordering="NONE"
side="BOTH"

View File

@@ -29,6 +29,9 @@ 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;
@@ -653,13 +656,6 @@ public final class Settings {
*/
public final Setting<Boolean> logAsToast = new Setting<>(false);
/**
* The time of how long the message in the pop-up will display
* <p>
* If below 1000L (1sec), it's better to disable this
*/
public final Setting<Long> toastTimer = new Setting<>(5000L);
/**
* Print all the debug messages to chat
*/
@@ -1089,6 +1085,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.

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

@@ -157,7 +157,7 @@ public final class BetterBlockPos extends BlockPos {
@Override
public BetterBlockPos relative(Direction dir) {
Vec3i vec = dir.getNormal();
Vec3i vec = dir.getUnitVec3i();
return new BetterBlockPos(x + vec.getX(), y + vec.getY(), z + vec.getZ());
}
@@ -166,7 +166,7 @@ public final class BetterBlockPos extends BlockPos {
if (dist == 0) {
return this;
}
Vec3i vec = dir.getNormal();
Vec3i vec = dir.getUnitVec3i();
return new BetterBlockPos(x + vec.getX() * dist, y + vec.getY() * dist, z + vec.getZ() * dist);
}

View File

@@ -25,6 +25,7 @@ import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.commands.Commands;
import net.minecraft.core.LayeredRegistryAccess;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.resources.RegistryDataLoader;
import net.minecraft.resources.ResourceKey;
@@ -42,6 +43,7 @@ import net.minecraft.server.packs.repository.ServerPacksSource;
import net.minecraft.server.packs.resources.CloseableResourceManager;
import net.minecraft.server.packs.resources.MultiPackResourceManager;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.tags.TagLoader;
import net.minecraft.world.RandomSequences;
import net.minecraft.world.flag.FeatureFlagSet;
import net.minecraft.world.item.Item;
@@ -229,8 +231,8 @@ public final class BlockOptionalMeta {
private static synchronized List<Item> drops(Block b) {
return drops.computeIfAbsent(b, block -> {
ResourceLocation lootTableLocation = block.getLootTable().location();
if (lootTableLocation.equals(BuiltInLootTables.EMPTY.location())) {
Optional<ResourceKey<LootTable>> optionalLootTableKey = block.getLootTable();
if (optionalLootTableKey.isEmpty()) {
return Collections.emptyList();
} else {
List<Item> items = new ArrayList<>();
@@ -251,13 +253,13 @@ public final class BlockOptionalMeta {
}
private static List<ItemStack> getDrops(Block state, LootParams.Builder params) {
ResourceKey<LootTable> lv = state.getLootTable();
if (lv == BuiltInLootTables.EMPTY) {
Optional<ResourceKey<LootTable>> lv = state.getLootTable();
if (lv.isEmpty()) {
return Collections.emptyList();
} else {
LootParams lv2 = params.withParameter(LootContextParams.BLOCK_STATE, state.defaultBlockState()).create(LootContextParamSets.BLOCK);
ServerLevelStub lv3 = (ServerLevelStub) lv2.getLevel();
LootTable lv4 = lv3.holder().getLootTable(lv);
LootTable lv4 = lv3.holder().getLootTable(lv.get());
return((ILootTable) lv4).invokeGetRandomItems(new LootContext.Builder(lv2).withOptionalRandomSeed(1).create(null));
}
}
@@ -307,39 +309,16 @@ public final class BlockOptionalMeta {
public static CompletableFuture<RegistryAccess> load() {
PackRepository packRepository = Minecraft.getInstance().getResourcePackRepository();
CloseableResourceManager closeableResourceManager = new MultiPackResourceManager(PackType.SERVER_DATA, packRepository.openAllSelected());
LayeredRegistryAccess<RegistryLayer> layeredRegistryAccess = loadAndReplaceLayer(
closeableResourceManager, RegistryLayer.createRegistryAccess(), RegistryLayer.WORLDGEN, RegistryDataLoader.WORLDGEN_REGISTRIES
LayeredRegistryAccess<RegistryLayer> layeredRegistryAccess = RegistryLayer.createRegistryAccess();
List<Registry.PendingTags<?>> pendingTags = TagLoader.loadTagsForExistingRegistries(
closeableResourceManager, layeredRegistryAccess.getLayer(RegistryLayer.STATIC)
);
return ReloadableServerResources.loadResources(
closeableResourceManager,
return ReloadableServerRegistries.reload(
layeredRegistryAccess,
WorldDataConfiguration.DEFAULT.enabledFeatures(),
Commands.CommandSelection.INTEGRATED,
2,
Runnable::run,
pendingTags,
closeableResourceManager,
Minecraft.getInstance()
).thenApply(reloadableServerResources -> reloadableServerResources.fullRegistries().get());
).thenApply(r -> r.layers().compositeAccess());
}
private static LayeredRegistryAccess<RegistryLayer> loadAndReplaceLayer(
ResourceManager resourceManager,
LayeredRegistryAccess<RegistryLayer> registryAccess,
RegistryLayer registryLayer,
List<RegistryDataLoader.RegistryData<?>> registryData
) {
RegistryAccess.Frozen frozen = loadLayer(resourceManager, registryAccess, registryLayer, registryData);
return registryAccess.replaceFrom(registryLayer, frozen);
}
private static RegistryAccess.Frozen loadLayer(
ResourceManager resourceManager,
LayeredRegistryAccess<RegistryLayer> registryAccess,
RegistryLayer registryLayer,
List<RegistryDataLoader.RegistryData<?>> registryData
) {
RegistryAccess.Frozen frozen = registryAccess.getAccessForLoading(registryLayer);
return RegistryDataLoader.load(resourceManager, frozen, registryData);
}
}
}

View File

@@ -21,12 +21,16 @@ import baritone.api.BaritoneAPI;
import baritone.api.Settings;
import net.minecraft.client.Minecraft;
import net.minecraft.core.Direction;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.Vec3i;
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;
@@ -220,7 +224,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])),
@@ -237,8 +242,8 @@ public class SettingsUtil {
BlockUtils::blockToString
),
ITEM(
Item.class,
str -> BuiltInRegistries.ITEM.get(ResourceLocation.parse(str.trim())), // TODO this now returns AIR on failure instead of null, is that an issue?
Item.class,
str -> BuiltInRegistries.ITEM.get(ResourceLocation.parse(str.trim())).map(Holder.Reference::value).orElse(null),
item -> BuiltInRegistries.ITEM.getKey(item).toString()
),
LIST() {

View File

@@ -17,65 +17,13 @@
package baritone.api.utils.gui;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.toasts.Toast;
import net.minecraft.client.gui.components.toasts.ToastComponent;
import net.minecraft.client.gui.components.toasts.SystemToast;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
public class BaritoneToast implements Toast {
private String title;
private String subtitle;
private long firstDrawTime;
private boolean newDisplay;
private long totalShowTime;
public BaritoneToast(Component titleComponent, Component subtitleComponent, long totalShowTime) {
this.title = titleComponent.getString();
this.subtitle = subtitleComponent == null ? null : subtitleComponent.getString();
this.totalShowTime = totalShowTime;
}
public Visibility render(GuiGraphics gui, ToastComponent toastGui, long delta) {
if (this.newDisplay) {
this.firstDrawTime = delta;
this.newDisplay = false;
}
//TODO: check
gui.blit(ResourceLocation.parse("textures/gui/toasts.png"), 0, 0, 0, 32, 160, 32);
if (this.subtitle == null) {
gui.drawString(toastGui.getMinecraft().font, this.title, 18, 12, -11534256);
} else {
gui.drawString(toastGui.getMinecraft().font, this.title, 18, 7, -11534256);
gui.drawString(toastGui.getMinecraft().font, this.subtitle, 18, 18, -16777216);
}
return delta - this.firstDrawTime < totalShowTime ? Visibility.SHOW : Visibility.HIDE;
}
public void setDisplayedText(Component titleComponent, Component subtitleComponent) {
this.title = titleComponent.getString();
this.subtitle = subtitleComponent == null ? null : subtitleComponent.getString();
this.newDisplay = true;
}
public static void addOrUpdate(ToastComponent toast, Component title, Component subtitle, long totalShowTime) {
BaritoneToast baritonetoast = toast.getToast(BaritoneToast.class, new Object());
if (baritonetoast == null) {
toast.addToast(new BaritoneToast(title, subtitle, totalShowTime));
} else {
baritonetoast.setDisplayedText(title, subtitle);
}
}
public class BaritoneToast {
private static final SystemToast.SystemToastId BARITONE_TOAST_ID = new SystemToast.SystemToastId(5000L);
public static void addOrUpdate(Component title, Component subtitle) {
addOrUpdate(Minecraft.getInstance().getToasts(), title, subtitle, baritone.api.BaritoneAPI.getSettings().toastTimer.value);
SystemToast.addOrUpdate(Minecraft.getInstance().getToastManager(), BARITONE_TOAST_ID, title, subtitle);
}
}

View File

@@ -32,6 +32,7 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Optional;
@@ -81,13 +82,13 @@ public abstract class MixinLivingEntity extends Entity {
}
@Inject(
method = "travel",
method = "updateFallFlyingMovement",
at = @At(
value = "INVOKE",
target = "net/minecraft/world/entity/LivingEntity.getLookAngle()Lnet/minecraft/world/phys/Vec3;"
)
)
private void onPreElytraMove(Vec3 direction, CallbackInfo ci) {
private void onPreElytraMove(Vec3 direction, final CallbackInfoReturnable<Vec3> cir) {
this.getBaritone().ifPresent(baritone -> {
this.elytraRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.getYRot(), this.getXRot());
baritone.getGameEventHandler().onPlayerRotationMove(this.elytraRotationEvent);
@@ -97,14 +98,14 @@ public abstract class MixinLivingEntity extends Entity {
}
@Inject(
method = "travel",
method = "travelFallFlying",
at = @At(
value = "INVOKE",
target = "net/minecraft/world/entity/LivingEntity.move(Lnet/minecraft/world/entity/MoverType;Lnet/minecraft/world/phys/Vec3;)V",
shift = At.Shift.AFTER
)
)
private void onPostElytraMove(Vec3 direction, CallbackInfo ci) {
private void onPostElytraMove(final CallbackInfo ci) {
if (this.elytraRotationEvent != null) {
this.setYRot(this.elytraRotationEvent.getOriginal().getYaw());
this.setXRot(this.elytraRotationEvent.getOriginal().getPitch());

View File

@@ -20,6 +20,7 @@ package baritone.launch.mixins;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.event.events.RenderEvent;
import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Camera;
import net.minecraft.client.DeltaTracker;
@@ -44,7 +45,7 @@ public class MixinWorldRenderer {
method = "renderLevel",
at = @At("RETURN")
)
private void onStartHand(final DeltaTracker deltaTracker, final boolean bl, final Camera camera, final GameRenderer gameRenderer, final LightTexture lightTexture, final Matrix4f matrix4f, final Matrix4f matrix4f2, final CallbackInfo ci) {
private void onStartHand(final GraphicsResourceAllocator graphicsResourceAllocator, final DeltaTracker deltaTracker, final boolean bl, final Camera camera, final GameRenderer gameRenderer, final LightTexture lightTexture, final Matrix4f matrix4f, final Matrix4f matrix4f2, final CallbackInfo ci) {
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
PoseStack poseStack = new PoseStack();
poseStack.mulPose(matrix4f);

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

@@ -84,7 +84,7 @@ public final class ChunkPacker {
Block block = state.getBlock();
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(block)) {
String name = BlockUtils.blockToString(block);
specialBlocks.computeIfAbsent(name, b -> new ArrayList<>()).add(new BlockPos(x, y+chunk.getMinBuildHeight(), z));
specialBlocks.computeIfAbsent(name, b -> new ArrayList<>()).add(new BlockPos(x, y+chunk.getMinY(), z));
}
}
}

View File

@@ -156,7 +156,7 @@ public enum FasterWorldScanner implements IWorldScanner {
long chunkX = (long) pos.x << 4;
long chunkZ = (long) pos.z << 4;
int playerSectionY = (ctx.playerFeet().y - ctx.world().getMinBuildHeight()) >> 4;
int playerSectionY = (ctx.playerFeet().y - ctx.world().getMinY()) >> 4;
return collectChunkSections(lookup, chunkProvider.getChunk(pos.x, pos.z, false), chunkX, chunkZ, playerSectionY).stream();
}
@@ -165,7 +165,7 @@ public enum FasterWorldScanner implements IWorldScanner {
private List<BlockPos> collectChunkSections(BlockOptionalMetaLookup lookup, LevelChunk chunk, long chunkX, long chunkZ, int playerSection) {
// iterate over sections relative to player
List<BlockPos> blocks = new ArrayList<>();
int chunkY = chunk.getMinBuildHeight();
int chunkY = chunk.getMinY();
LevelChunkSection[] sections = chunk.getSections();
int l = sections.length;
int i = playerSection - 1;

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

@@ -228,12 +228,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

@@ -41,8 +41,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 +96,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;

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

View File

@@ -421,7 +421,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) {

View File

@@ -140,7 +140,7 @@ public class MovementFall extends Movement {
}
state.setInput(Input.MOVE_FORWARD, true);
}
Vec3i avoid = Optional.ofNullable(avoid()).map(Direction::getNormal).orElse(null);
Vec3i avoid = Optional.ofNullable(avoid()).map(Direction::getUnitVec3i).orElse(null);
if (avoid == null) {
avoid = src.subtract(dest);
} else {

View File

@@ -30,6 +30,8 @@ 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;
@@ -42,17 +44,13 @@ 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;
import com.google.common.collect.ImmutableSet;
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.NbtAccounter;
import net.minecraft.nbt.NbtIo;
import net.minecraft.util.Tuple;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.BlockItem;
@@ -77,7 +75,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;
@@ -120,6 +117,12 @@ 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
@@ -230,19 +233,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()), NbtAccounter.unlimitedHeap()), 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");
@@ -373,7 +370,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);
@@ -717,13 +718,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 {
@@ -741,6 +745,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<>();

View File

@@ -310,7 +310,7 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro
if (!(ctx.world().getBlockState(pos.relative(dir)).getBlock() instanceof AirBlock)) {
continue;
}
Vec3 faceCenter = Vec3.atCenterOf(pos).add(Vec3.atLowerCornerOf(dir.getNormal()).scale(0.5));
Vec3 faceCenter = Vec3.atCenterOf(pos).add(Vec3.atLowerCornerOf(dir.getUnitVec3i()).scale(0.5));
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(), blockReachDistance);

View File

@@ -37,7 +37,7 @@ public class Selection implements ISelection {
max.z - min.z + 1
);
this.aabb = new AABB(this.min);
this.aabb = new AABB(min.x, min.y, min.z, max.x + 1, max.y + 1, max.z + 1);
}
@Override

View File

@@ -60,7 +60,7 @@ public final class BlockStateInterfaceAccessWrapper implements BlockGetter {
}
@Override
public int getMinBuildHeight() {
public int getMinY() {
return 0;
}

View File

@@ -24,7 +24,10 @@ import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.CoreShaders;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.ShaderProgram;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
@@ -50,7 +53,7 @@ public interface IRenderer {
static BufferBuilder startLines(Color color, float alpha, float lineWidth, boolean ignoreDepth) {
RenderSystem.enableBlend();
RenderSystem.setShader(GameRenderer::getPositionColorShader);
RenderSystem.setShader(CoreShaders.POSITION_COLOR);
RenderSystem.blendFuncSeparate(
GlStateManager.SourceFactor.SRC_ALPHA,
GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA,
@@ -65,7 +68,7 @@ public interface IRenderer {
if (ignoreDepth) {
RenderSystem.disableDepthTest();
}
RenderSystem.setShader(GameRenderer::getRendertypeLinesShader);
RenderSystem.setShader(CoreShaders.RENDERTYPE_LINES);
return tessellator.begin(VertexFormat.Mode.LINES, DefaultVertexFormat.POSITION_COLOR_NORMAL);
}
@@ -78,7 +81,7 @@ public interface IRenderer {
if (meshData != null) {
BufferUploader.drawWithShader(meshData);
}
if (ignoredDepth) {
RenderSystem.enableDepthTest();
}

View File

@@ -262,12 +262,12 @@ public final class PathRenderer implements IRenderer {
drawDankLitGoalBox(bufferBuilder, stack, color, minX, maxX, minZ, maxZ, minY, maxY, y1, y2, setupRender);
} else if (goal instanceof GoalXZ) {
GoalXZ goalPos = (GoalXZ) goal;
minY = ctx.world().getMinBuildHeight();
maxY = ctx.world().getMaxBuildHeight();
minY = ctx.world().getMinY();
maxY = ctx.world().getMaxY();
if (settings.renderGoalXZBeacon.value) {
//TODO: check
textureManager.bindForSetup(TEXTURE_BEACON_BEAM);
textureManager.getTexture(TEXTURE_BEACON_BEAM).bind();
if (settings.renderGoalIgnoreDepth.value) {
RenderSystem.disableDepthTest();
}

View File

@@ -18,8 +18,9 @@
package baritone.utils;
import baritone.api.utils.input.Input;
import net.minecraft.client.player.ClientInput;
public class PlayerMovementInput extends net.minecraft.client.player.Input {
public class PlayerMovementInput extends ClientInput {
private final InputOverrideHandler handler;
@@ -31,28 +32,36 @@ public class PlayerMovementInput extends net.minecraft.client.player.Input {
public void tick(boolean p_225607_1_, float f) {
this.leftImpulse = 0.0F;
this.forwardImpulse = 0.0F;
boolean jumping = handler.isInputForcedDown(Input.JUMP); // oppa gangnam style
this.jumping = handler.isInputForcedDown(Input.JUMP); // oppa gangnam style
if (this.up = handler.isInputForcedDown(Input.MOVE_FORWARD)) {
boolean up = handler.isInputForcedDown(Input.MOVE_FORWARD);
if (up) {
this.forwardImpulse++;
}
if (this.down = handler.isInputForcedDown(Input.MOVE_BACK)) {
boolean down = handler.isInputForcedDown(Input.MOVE_BACK);
if (down) {
this.forwardImpulse--;
}
if (this.left = handler.isInputForcedDown(Input.MOVE_LEFT)) {
boolean left = handler.isInputForcedDown(Input.MOVE_LEFT);
if (left) {
this.leftImpulse++;
}
if (this.right = handler.isInputForcedDown(Input.MOVE_RIGHT)) {
boolean right = handler.isInputForcedDown(Input.MOVE_RIGHT);
if (right) {
this.leftImpulse--;
}
if (this.shiftKeyDown = handler.isInputForcedDown(Input.SNEAK)) {
boolean sneaking = handler.isInputForcedDown(Input.SNEAK);
if (sneaking) {
this.leftImpulse *= 0.3D;
this.forwardImpulse *= 0.3D;
}
boolean sprinting = handler.isInputForcedDown(Input.SPRINT);
this.keyPresses = new net.minecraft.world.entity.player.Input(up, down, left, right, jumping, sneaking, sprinting);
}
}

View File

@@ -20,12 +20,17 @@ package baritone.utils;
import baritone.Baritone;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.Holder;
import net.minecraft.tags.ItemTags;
import net.minecraft.tags.TagKey;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.SwordItem;
import net.minecraft.world.item.TieredItem;
import net.minecraft.world.item.enchantment.*;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentEffectComponents;
import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.world.item.enchantment.ItemEnchantments;
import net.minecraft.world.item.enchantment.effects.EnchantmentAttributeEffect;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
@@ -55,6 +60,20 @@ public class ToolSet {
private final LocalPlayer player;
/**
* Used for evaluating the material cost of a tool.
* see {@link #getMaterialCost(ItemStack)}
* Prefer tools with lower material cost (lower index in this list).
*/
private static final List<TagKey<Item>> materialTagsPriorityList = List.of(
ItemTags.WOODEN_TOOL_MATERIALS,
ItemTags.STONE_TOOL_MATERIALS,
ItemTags.IRON_TOOL_MATERIALS,
ItemTags.GOLD_TOOL_MATERIALS,
ItemTags.DIAMOND_TOOL_MATERIALS,
ItemTags.NETHERITE_TOOL_MATERIALS
);
public ToolSet(LocalPlayer player) {
breakStrengthCache = new HashMap<>();
this.player = player;
@@ -79,20 +98,18 @@ public class ToolSet {
}
/**
* Evaluate the material cost of a possible tool. The priority matches the
* harvest level order; there is a chance for multiple at the same with modded tools
* but in that case we don't really care.
*
* Evaluate the material cost of a possible tool.
* If all else is equal, we want to prefer the tool with the lowest material cost.
* i.e. we want to prefer a wooden pickaxe over a stone pickaxe, if all else is equal.
* @param itemStack a possibly empty ItemStack
* @return values from 0 up
*/
private int getMaterialCost(ItemStack itemStack) {
if (itemStack.getItem() instanceof TieredItem) {
TieredItem tool = (TieredItem) itemStack.getItem();
return (int) tool.getTier().getAttackDamageBonus();
} else {
return -1;
for (int i = 0; i < materialTagsPriorityList.size(); i++) {
final TagKey<Item> tag = materialTagsPriorityList.get(i);
if (itemStack.is(tag)) return i;
}
return -1;
}
public boolean hasSilkTouch(ItemStack stack) {

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

@@ -84,7 +84,7 @@ public enum DefaultSchematicFormats implements ISchematicFormat {
case 6: //1.18-1.20
throw new UnsupportedOperationException("This litematic Version is too old.");
case 7: //1.21+
return new LitematicaSchematic(nbt, false);
return new LitematicaSchematic(nbt);
default:
throw new UnsupportedOperationException("Unsuported Version of a Litematica Schematic");
}

View File

@@ -17,19 +17,23 @@
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.Holder;
import net.minecraft.core.Vec3i;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
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 +43,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 +69,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);
}
/**
@@ -94,8 +83,14 @@ public final class LitematicaSchematic extends StaticSchematic {
BlockState[] blockList = new BlockState[blockStatePalette.size()];
for (int i = 0; i < blockStatePalette.size(); i++) {
Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse((((CompoundTag) blockStatePalette.get(i)).getString("Name"))));
CompoundTag properties = ((CompoundTag) blockStatePalette.get(i)).getCompound("Properties");
CompoundTag tag = (CompoundTag) blockStatePalette.get(i);
ResourceLocation blockKey = ResourceLocation.tryParse(tag.getString("Name"));
Block block = blockKey == null
? Blocks.AIR
: BuiltInRegistries.BLOCK.get(blockKey)
.map(Holder.Reference::value)
.orElse(Blocks.AIR);
CompoundTag properties = tag.getCompound("Properties");
blockList[i] = getBlockState(block, properties);
}
@@ -110,7 +105,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 +141,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 +161,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 +182,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

@@ -18,12 +18,14 @@
package baritone.utils.schematic.format.defaults;
import baritone.utils.schematic.StaticSchematic;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.datafix.fixes.ItemIdFix;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
/**
@@ -63,7 +65,13 @@ public final class MCEditSchematic extends StaticSchematic {
// additional is 0 through 15 inclusive since it's & 0xF above
blockID |= additional[blockInd] << 8;
}
Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.tryParse(ItemIdFix.getItem(blockID)));
ResourceLocation blockKey = ResourceLocation.tryParse(ItemIdFix.getItem(blockID));
Block block = blockKey == null
? Blocks.AIR
: BuiltInRegistries.BLOCK.get(blockKey)
.map(Holder.Reference::value)
.orElse(Blocks.AIR);
// int meta = metadata[blockInd] & 0xFF;
// this.states[x][z][y] = block.getStateFromMeta(meta);
this.states[x][z][y] = block.defaultBlockState();

View File

@@ -25,11 +25,14 @@ import java.util.Map;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.Property;
@@ -107,7 +110,9 @@ public final class SpongeSchematic extends StaticSchematic {
private BlockState deserialize() {
if (this.blockState == null) {
Block block = BuiltInRegistries.BLOCK.get(this.resourceLocation);
Block block = BuiltInRegistries.BLOCK.get(this.resourceLocation)
.map(Holder.Reference::value)
.orElse(Blocks.AIR);
this.blockState = block.defaultBlockState();
this.properties.keySet().stream().sorted(String::compareTo).forEachOrdered(key -> {

View File

@@ -17,15 +17,25 @@
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.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 +58,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<>();
WorldSchematic 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);
}
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;
}
return tempSchem;
}
}

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, false, false, 0, 0);
throw new LinkageError();
}
}

View File

@@ -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'
implementation('net.minecraft:launchwrapper:of-2.3') {