Skip to content

1.21.2/.3 update #4970

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 28 commits into from
Nov 17, 2024
Merged
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3d4afde
1.21.2 update
Big-Iron-Cheems Oct 19, 2024
faca0a2
Some fixes
Wide-Cat Oct 19, 2024
9e6cd91
More fixes
Big-Iron-Cheems Oct 22, 2024
957e741
Even more fixes
Wide-Cat Oct 26, 2024
862de25
Merge remote-tracking branch 'upstream/master' into 1.21.2-update
Big-Iron-Cheems Oct 29, 2024
a812a8e
Some fixes
MineGame159 Nov 1, 2024
3fa2a21
Fix 3D rendering and rewrite WireframeEntityRenderer
MineGame159 Nov 1, 2024
b83a0bd
Fix PacketUtils
MineGame159 Nov 1, 2024
e4fd6c2
Fix Xray and Fullbright
MineGame159 Nov 1, 2024
4c9d031
Turns out previous commit could be much simpler
MineGame159 Nov 1, 2024
60f2005
Few more fixes
MineGame159 Nov 3, 2024
e1d00b8
WIP Chams fixes
MineGame159 Nov 3, 2024
086eccb
Merge remote-tracking branch 'refs/remotes/upstream/master' into 1.21…
Big-Iron-Cheems Nov 3, 2024
49c4251
1.21.3 update
Big-Iron-Cheems Nov 3, 2024
006aec8
Stuff
MineGame159 Nov 3, 2024
c84577a
Merge branch 'master' into 1.21.2-update
Wide-Cat Nov 3, 2024
5940313
fixes for rotations, wireframe rendering, chams (somewhat)
Wide-Cat Nov 4, 2024
bf9197f
remove unused entries from the access widener
Wide-Cat Nov 6, 2024
1b7c731
Merge branch 'MeteorDevelopment:master' into 1.21.2-update
Big-Iron-Cheems Nov 7, 2024
e9c91f7
Update mixins using `@Local`
Big-Iron-Cheems Nov 7, 2024
3ac242e
Fix entity shader rendering
MineGame159 Nov 7, 2024
6c16e14
Add missing meteor$ prefix for methods inside mixin interfaces
MineGame159 Nov 7, 2024
cd1ac30
Merge branch 'master' into 1.21.2-update
Wide-Cat Nov 7, 2024
a6337ee
Minor cleanup
Big-Iron-Cheems Nov 8, 2024
04e889b
Cancellable mixin correction
Big-Iron-Cheems Nov 8, 2024
2ee3a54
Fix ItemPhysics
Big-Iron-Cheems Nov 16, 2024
b7f9e46
fixup! Fix ItemPhysics
Big-Iron-Cheems Nov 16, 2024
8e68fe4
Bump dependencies
Big-Iron-Cheems Nov 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
id "fabric-loom" version "1.7-SNAPSHOT"
id "fabric-loom" version "1.8-SNAPSHOT"
id "maven-publish"
id "com.github.johnrengelman.shadow" version "8.1.1"
}
18 changes: 9 additions & 9 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
org.gradle.jvmargs=-Xmx2G

# Fabric (https://fabricmc.net/develop)
minecraft_version=1.21.1
yarn_mappings=1.21.1+build.3
loader_version=0.15.11
fapi_version=0.102.1+1.21.1
minecraft_version=1.21.3
yarn_mappings=1.21.3+build.2
loader_version=0.16.9
fapi_version=0.108.0+1.21.3

# Mod Properties
mod_version=0.5.8
@@ -14,16 +14,16 @@ archives_base_name=meteor-client
# Dependency Versions

# Baritone (https://github.com/MeteorDevelopment/baritone)
baritone_version=1.21
baritone_version=1.21.3

# Sodium (https://github.com/CaffeineMC/sodium-fabric)
sodium_version=mc1.21-0.6.0-beta.2-fabric
sodium_version=mc1.21.3-0.6.0-fabric

# Lithium (https://github.com/CaffeineMC/lithium-fabric)
lithium_version=mc1.21.1-0.14.0-beta.1
lithium_version=mc1.21.3-0.14.2

# Iris (https://github.com/IrisShaders/Iris)
iris_version=1.7.3+1.21
iris_version=1.8.0+1.21.3-fabric

# Orbit (https://github.com/MeteorDevelopment/orbit)
orbit_version=0.2.4
@@ -41,7 +41,7 @@ reflections_version=0.10.2
netty_version=4.1.90.Final

# ViaFabricPlus (https://github.com/ViaVersion/ViaFabricPlus)
viafabricplus_version=3.4.4
viafabricplus_version=3.5.1

# WaybackAuthLib (https://github.com/FlorianMichael/WaybackAuthLib)
waybackauthlib_version=1.0.1
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ public class GameRendererTransformer extends AsmTransformer {
public GameRendererTransformer() {
super(mapClassName("net/minecraft/class_757"));

getFovMethod = new MethodInfo("net/minecraft/class_4184", null, new Descriptor("Lnet/minecraft/class_4184;", "F", "Z", "D"), true);
getFovMethod = new MethodInfo("net/minecraft/class_4184", null, new Descriptor("Lnet/minecraft/class_4184;", "F", "Z", "F"), true);
}

@Override
@@ -30,7 +30,7 @@ public void transform(ClassNode klass) {

//noinspection DataFlowIssue
for (AbstractInsnNode insn : method.instructions) {
if (insn instanceof LdcInsnNode in && in.cst instanceof Double && (double) in.cst == 90) {
if (insn instanceof LdcInsnNode in && in.cst instanceof Float && (float) in.cst == 90) {
InsnList insns = new InsnList();
generateEventCall(insns, new LdcInsnNode(in.cst));

@@ -39,14 +39,14 @@ public void transform(ClassNode klass) {
injectionCount++;
}
else if (
(insn instanceof MethodInsnNode in1 && in1.name.equals("intValue") && insn.getNext() instanceof InsnNode _in && _in.getOpcode() == Opcodes.I2D)
(insn instanceof MethodInsnNode in1 && in1.name.equals("intValue") && insn.getNext() instanceof InsnNode _in && _in.getOpcode() == Opcodes.I2F)
||
(insn instanceof MethodInsnNode in2 && in2.owner.equals(klass.name) && in2.name.startsWith("redirect") && in2.name.endsWith("getFov")) // Wi Zoom compatibility
) {
InsnList insns = new InsnList();

insns.add(new VarInsnNode(Opcodes.DSTORE, method.maxLocals));
generateEventCall(insns, new VarInsnNode(Opcodes.DLOAD, method.maxLocals));
insns.add(new VarInsnNode(Opcodes.FSTORE, method.maxLocals));
generateEventCall(insns, new VarInsnNode(Opcodes.FLOAD, method.maxLocals));

method.instructions.insert(insn.getNext(), insns);
injectionCount++;
@@ -59,9 +59,9 @@ else if (
private void generateEventCall(InsnList insns, AbstractInsnNode loadPreviousFov) {
insns.add(new FieldInsnNode(Opcodes.GETSTATIC, "meteordevelopment/meteorclient/MeteorClient", "EVENT_BUS", "Lmeteordevelopment/orbit/IEventBus;"));
insns.add(loadPreviousFov);
insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "meteordevelopment/meteorclient/events/render/GetFovEvent", "get", "(D)Lmeteordevelopment/meteorclient/events/render/GetFovEvent;"));
insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "meteordevelopment/meteorclient/events/render/GetFovEvent", "get", "(F)Lmeteordevelopment/meteorclient/events/render/GetFovEvent;"));
insns.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, "meteordevelopment/orbit/IEventBus", "post", "(Ljava/lang/Object;)Ljava/lang/Object;"));
insns.add(new TypeInsnNode(Opcodes.CHECKCAST, "meteordevelopment/meteorclient/events/render/GetFovEvent"));
insns.add(new FieldInsnNode(Opcodes.GETFIELD, "meteordevelopment/meteorclient/events/render/GetFovEvent", "fov", "D"));
insns.add(new FieldInsnNode(Opcodes.GETFIELD, "meteordevelopment/meteorclient/events/render/GetFovEvent", "fov", "F"));
}
}
Original file line number Diff line number Diff line change
@@ -106,14 +106,14 @@ public RegistryEntry.Reference<T> parse(StringReader reader) throws CommandSynta
Identifier identifier = Identifier.fromCommandInput(reader);
RegistryKey<T> registryKey = RegistryKey.of(this.registryRef, identifier);
return MinecraftClient.getInstance().getNetworkHandler().getRegistryManager()
.getWrapperOrThrow(this.registryRef)
.getOrThrow(this.registryRef)
.getOptional(registryKey)
.orElseThrow(() -> NOT_FOUND_EXCEPTION.createWithContext(reader, identifier, this.registryRef.getValue()));
}

@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
return CommandSource.suggestIdentifiers(MinecraftClient.getInstance().getNetworkHandler().getRegistryManager().getWrapperOrThrow(this.registryRef).streamKeys().map(RegistryKey::getValue), builder);
return CommandSource.suggestIdentifiers(MinecraftClient.getInstance().getNetworkHandler().getRegistryManager().getOrThrow(this.registryRef).streamKeys().map(RegistryKey::getValue), builder);
}

@Override
Original file line number Diff line number Diff line change
@@ -60,6 +60,6 @@ private void damagePlayer(int amount) {
}

private void sendPositionPacket(double x, double y, double z, boolean onGround) {
mc.player.networkHandler.sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(x, y, z, onGround));
mc.player.networkHandler.sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(x, y, z, onGround, mc.player.horizontalCollision));
}
}
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@
import meteordevelopment.meteorclient.commands.Command;
import net.minecraft.command.CommandSource;
import net.minecraft.network.packet.c2s.play.PlayerInputC2SPacket;
import net.minecraft.util.PlayerInput;

public class DismountCommand extends Command {
public DismountCommand() {
@@ -18,7 +19,8 @@ public DismountCommand() {
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder) {
builder.executes(context -> {
mc.getNetworkHandler().sendPacket(new PlayerInputC2SPacket(0, 0, false, true));
PlayerInput sneak = new PlayerInput(false, false, false, false, false, true, false);
mc.getNetworkHandler().sendPacket(new PlayerInputC2SPacket(sneak));
return SINGLE_SUCCESS;
});
}
Original file line number Diff line number Diff line change
@@ -96,7 +96,7 @@ private void one(CommandContext<CommandSource> context, ToIntFunction<Enchantmen
private void all(boolean onlyPossible, ToIntFunction<Enchantment> level) throws CommandSyntaxException {
ItemStack itemStack = tryGetItemStack();

mc.getNetworkHandler().getRegistryManager().getOptionalWrapper(RegistryKeys.ENCHANTMENT).ifPresent(registry -> {
mc.getNetworkHandler().getRegistryManager().getOptional(RegistryKeys.ENCHANTMENT).ifPresent(registry -> {
registry.streamEntries().forEach(enchantment -> {
if (!onlyPossible || enchantment.value().isAcceptableItem(itemStack)) {
Utils.addEnchantment(itemStack, enchantment, level.applyAsInt(enchantment.value()));
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ public FovCommand() {
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder) {
builder.then(argument("fov", IntegerArgumentType.integer(0, 180)).executes(context -> {
((ISimpleOption) (Object) mc.options.getFov()).set(context.getArgument("fov", Integer.class));
((ISimpleOption) (Object) mc.options.getFov()).meteor$set(context.getArgument("fov", Integer.class));
return SINGLE_SUCCESS;
}));
}
Original file line number Diff line number Diff line change
@@ -79,7 +79,7 @@ public void build(LiteralArgumentBuilder<CommandSource> builder) {

if (validBasic(stack)) {
ComponentMap components = ComponentMapArgumentType.getComponentMap(ctx, "component");
ComponentMapImpl stackComponents = (ComponentMapImpl) stack.getComponents();
MergedComponentMap stackComponents = (MergedComponentMap) stack.getComponents();

DataResult<Unit> dataResult = ItemStack.validateComponents(components);
dataResult.getOrThrow(MALFORMED_ITEM_EXCEPTION::create);
@@ -115,7 +115,7 @@ public void build(LiteralArgumentBuilder<CommandSource> builder) {

ComponentType<?> componentType = Registries.DATA_COMPONENT_TYPE.get(componentTypeKey);

ComponentMapImpl components = (ComponentMapImpl) stack.getComponents();
MergedComponentMap components = (MergedComponentMap) stack.getComponents();
components.applyChanges(ComponentChanges.builder().remove(componentType).build());

setStack(stack);
Original file line number Diff line number Diff line change
@@ -34,8 +34,8 @@
import java.util.Map;

public class NotebotCommand extends Command {
private final static SimpleCommandExceptionType INVALID_SONG = new SimpleCommandExceptionType(Text.literal("Invalid song."));
private final static DynamicCommandExceptionType INVALID_PATH = new DynamicCommandExceptionType(object -> Text.literal("'%s' is not a valid path.".formatted(object)));
private static final SimpleCommandExceptionType INVALID_SONG = new SimpleCommandExceptionType(Text.literal("Invalid song."));
private static final DynamicCommandExceptionType INVALID_PATH = new DynamicCommandExceptionType(object -> Text.literal("'%s' is not a valid path.".formatted(object)));

int ticks = -1;
private final Map<Integer, List<Note>> song = new HashMap<>(); // tick -> notes
@@ -144,7 +144,7 @@ private void onTick(TickEvent.Post event) {

@EventHandler
private void onReadPacket(PacketEvent.Receive event) {
if (event.packet instanceof PlaySoundS2CPacket sound && sound.getSound().value().getId().getPath().contains("note_block")) {
if (event.packet instanceof PlaySoundS2CPacket sound && sound.getSound().value().id().getPath().contains("note_block")) {
if (ticks == -1) ticks = 0;
List<Note> notes = song.computeIfAbsent(ticks, tick -> new ArrayList<>());
var note = getNote(sound);
@@ -212,7 +212,7 @@ private Note getNote(PlaySoundS2CPacket soundPacket) {
}

private NoteBlockInstrument getInstrumentFromSound(SoundEvent sound) {
String path = sound.getId().getPath();
String path = sound.id().getPath();
if (path.contains("harp"))
return NoteBlockInstrument.HARP;
else if (path.contains("basedrum"))
Original file line number Diff line number Diff line change
@@ -11,8 +11,9 @@
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import meteordevelopment.meteorclient.MeteorClient;
import meteordevelopment.meteorclient.commands.Command;
import meteordevelopment.meteorclient.mixin.MapRendererAccessor;
import meteordevelopment.meteorclient.mixin.MapTextureManagerAccessor;
import net.minecraft.client.render.MapRenderer;
import net.minecraft.client.texture.MapTextureManager;
import net.minecraft.command.CommandSource;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.item.FilledMapItem;
@@ -70,8 +71,8 @@ private void saveMap(int scale) throws CommandSyntaxException {
File path = getPath();
if (path == null) throw OOPS.create();

MapRenderer mapRenderer = mc.gameRenderer.getMapRenderer();
MapRenderer.MapTexture texture = ((MapRendererAccessor) mapRenderer).invokeGetMapTexture(map.get(DataComponentTypes.MAP_ID), state);
MapRenderer mapRenderer = mc.gameRenderer.getClient().getMapRenderer();
MapTextureManager.MapTexture texture = ((MapTextureManagerAccessor) mapRenderer).invokeGetMapTexture(map.get(DataComponentTypes.MAP_ID), state);
if (texture.texture.getImage() == null) throw OOPS.create();

try {
Original file line number Diff line number Diff line change
@@ -49,10 +49,10 @@ public void build(LiteralArgumentBuilder<CommandSource> builder) {
// No vehicle version
// For each 10 blocks, send a player move packet with no delta
for (int packetNumber = 0; packetNumber < (packetsRequired - 1); packetNumber++) {
mc.player.networkHandler.sendPacket(new PlayerMoveC2SPacket.OnGroundOnly(true));
mc.player.networkHandler.sendPacket(new PlayerMoveC2SPacket.OnGroundOnly(true, mc.player.horizontalCollision));
}
// Now send the final player move packet
mc.player.networkHandler.sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(mc.player.getX(), mc.player.getY() + blocks, mc.player.getZ(), true));
mc.player.networkHandler.sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(mc.player.getX(), mc.player.getY() + blocks, mc.player.getZ(), true, mc.player.horizontalCollision));
mc.player.setPosition(mc.player.getX(), mc.player.getY() + blocks, mc.player.getZ());
}

Original file line number Diff line number Diff line change
@@ -84,7 +84,7 @@ private String waypointFullPos(Waypoint waypoint) {
private int addWaypoint(CommandContext<CommandSource> context, boolean withCoords) {
if (mc.player == null) return -1;

BlockPos pos = withCoords ? context.getArgument("pos", PosArgument.class).toAbsoluteBlockPos(mc.player.getCommandSource()) : mc.player.getBlockPos().up(2);
BlockPos pos = withCoords ? context.getArgument("pos", PosArgument.class).toAbsoluteBlockPos(mc.player.getCommandSource(mc.getServer().getOverworld())) : mc.player.getBlockPos().up(2);
Waypoint waypoint = new Waypoint.Builder()
.name(StringArgumentType.getString(context, "waypoint"))
.pos(pos)
Original file line number Diff line number Diff line change
@@ -8,9 +8,9 @@
public class GetFovEvent {
private static final GetFovEvent INSTANCE = new GetFovEvent();

public double fov;
public float fov;

public static GetFovEvent get(double fov) {
public static GetFovEvent get(float fov) {
INSTANCE.fov = fov;
return INSTANCE;
}
Original file line number Diff line number Diff line change
@@ -6,33 +6,32 @@
package meteordevelopment.meteorclient.events.render;

import meteordevelopment.meteorclient.events.Cancellable;
import meteordevelopment.meteorclient.mixininterface.IEntityRenderState;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.state.ItemEntityRenderState;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.ItemEntity;
import net.minecraft.util.math.random.Random;

public class RenderItemEntityEvent extends Cancellable {
private static final RenderItemEntityEvent INSTANCE = new RenderItemEntityEvent();

public ItemEntity itemEntity;
public float f;
public ItemEntityRenderState renderState;
public float tickDelta;
public MatrixStack matrixStack;
public VertexConsumerProvider vertexConsumerProvider;
public int light;
public Random random;
public ItemRenderer itemRenderer;

public static RenderItemEntityEvent get(ItemEntity itemEntity, float f, float tickDelta, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light, Random random, ItemRenderer itemRenderer) {
public static RenderItemEntityEvent get(ItemEntityRenderState renderState, float tickDelta, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light, ItemRenderer itemRenderer) {
INSTANCE.setCancelled(false);
INSTANCE.itemEntity = itemEntity;
INSTANCE.f = f;
INSTANCE.itemEntity = (ItemEntity) ((IEntityRenderState) renderState).meteor$getEntity();
INSTANCE.renderState = renderState;
INSTANCE.tickDelta = tickDelta;
INSTANCE.matrixStack = matrixStack;
INSTANCE.vertexConsumerProvider = vertexConsumerProvider;
INSTANCE.light = light;
INSTANCE.random = random;
INSTANCE.itemRenderer = itemRenderer;
return INSTANCE;
}
Original file line number Diff line number Diff line change
@@ -344,7 +344,7 @@ private void blockDataW(WTable table, BlockDataSetting<?> setting) {

private void potionW(WTable table, PotionSetting setting) {
WHorizontalList list = table.add(theme.horizontalList()).expandX().widget();
WItemWithLabel item = list.add(theme.itemWithLabel(setting.get().potion, I18n.translate(setting.get().potion.getTranslationKey()))).widget();
WItemWithLabel item = list.add(theme.itemWithLabel(setting.get().potion, I18n.translate(setting.get().potion.getItem().getTranslationKey()))).widget();

WButton button = list.add(theme.button("Select")).expandCellX().widget();
button.action = () -> {
Original file line number Diff line number Diff line change
@@ -106,7 +106,7 @@ public void endRender() {

r.render(drawContext.getMatrices());

GL.bindTexture(TEXTURE.getGlId());
GL.getTexture(TEXTURE.getGlId());
rTex.render(drawContext.getMatrices());

// Normal text
Original file line number Diff line number Diff line change
@@ -84,13 +84,9 @@ private void addPath(Path path) {

table.add(theme.label(FilenameUtils.getBaseName(path.getFileName().toString()))).expandCellX();
WButton load = table.add(theme.button("Load")).right().widget();
load.action = () -> {
notebot.loadSong(path.toFile());
};
load.action = () -> notebot.loadSong(path.toFile());
WButton preview = table.add(theme.button("Preview")).right().widget();
preview.action = () -> {
notebot.previewSong(path.toFile());
};
preview.action = () -> notebot.previewSong(path.toFile());

table.row();
}
Original file line number Diff line number Diff line change
@@ -10,14 +10,13 @@
import meteordevelopment.meteorclient.gui.widgets.containers.WHorizontalList;
import meteordevelopment.meteorclient.gui.widgets.pressable.WButton;
import meteordevelopment.meteorclient.systems.accounts.Account;
import meteordevelopment.meteorclient.systems.accounts.AccountType;
import meteordevelopment.meteorclient.systems.accounts.TokenAccount;
import meteordevelopment.meteorclient.utils.render.color.Color;

import static meteordevelopment.meteorclient.MeteorClient.mc;

public class AccountInfoScreen extends WindowScreen {
private Account<?> account;
private final Account<?> account;

public AccountInfoScreen(GuiTheme theme, Account<?> account) {
super(theme, account.getUsername() + " details");
Original file line number Diff line number Diff line change
@@ -97,7 +97,7 @@ private void generateWidgets() {
try {
Identifier id = entry.contains(":") ? Identifier.of(entry) : Identifier.ofVanilla(entry);
addValue(RegistryKey.of(registryKey, id));
} catch (InvalidIdentifierException e) {}
} catch (InvalidIdentifierException ignored) {}
};

table.add(theme.verticalSeparator()).expandWidgetY();
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ public void initWidgets() {
WTable table = add(theme.table()).expandX().widget();

for (MyPotion potion : MyPotion.values()) {
table.add(theme.itemWithLabel(potion.potion, I18n.translate(potion.potion.getTranslationKey())));
table.add(theme.itemWithLabel(potion.potion, I18n.translate(potion.potion.getItem().getTranslationKey())));

WButton select = table.add(theme.button("Select")).widget();
select.action = () -> {
Loading