From ad476378effa1dfd5fbef9c4d4cb5eadb9954d32 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sat, 16 Apr 2022 03:15:46 +0800 Subject: Add shapeless indicator --- .../gui/widgets/DelegateWidgetWithBounds.java | 42 ++++ .../rei/api/client/gui/widgets/Widgets.java | 258 ++++++++------------- .../me/shedaniel/rei/impl/ClientInternals.java | 13 ++ .../crafting/DefaultCraftingCategory.java | 3 + .../displays/crafting/DefaultCraftingDisplay.java | 4 + .../displays/crafting/DefaultShapelessDisplay.java | 5 + .../gui/widget/DelegateWidgetWithTranslate.java | 86 +++++++ .../impl/client/gui/widget/InternalWidgets.java | 83 ++++--- .../rei/impl/client/gui/widget/MergedWidget.java | 66 ++++++ .../client/gui/widget/RendererWrappedWidget.java | 72 ++++++ .../client/gui/widget/VanillaWrappedWidget.java | 82 +++++++ .../assets/roughlyenoughitems/lang/de_de.json | 50 ++++ .../assets/roughlyenoughitems/lang/en_us.json | 3 +- .../assets/roughlyenoughitems/lang/pt_br.json | 57 +++-- .../assets/roughlyenoughitems/lang/zh_cn.json | 4 +- .../assets/roughlyenoughitems/lang/zh_tw.json | 4 +- 16 files changed, 609 insertions(+), 223 deletions(-) create mode 100644 api/src/main/java/me/shedaniel/rei/api/client/gui/widgets/DelegateWidgetWithBounds.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/DelegateWidgetWithTranslate.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/MergedWidget.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/RendererWrappedWidget.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/VanillaWrappedWidget.java diff --git a/api/src/main/java/me/shedaniel/rei/api/client/gui/widgets/DelegateWidgetWithBounds.java b/api/src/main/java/me/shedaniel/rei/api/client/gui/widgets/DelegateWidgetWithBounds.java new file mode 100644 index 000000000..cf2a9e025 --- /dev/null +++ b/api/src/main/java/me/shedaniel/rei/api/client/gui/widgets/DelegateWidgetWithBounds.java @@ -0,0 +1,42 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.api.client.gui.widgets; + +import me.shedaniel.math.Rectangle; + +import java.util.function.Supplier; + +public class DelegateWidgetWithBounds extends DelegateWidget { + private final Supplier bounds; + + public DelegateWidgetWithBounds(Widget widget, Supplier bounds) { + super(widget); + this.bounds = bounds; + } + + @Override + public Rectangle getBounds() { + return bounds.get(); + } +} \ No newline at end of file diff --git a/api/src/main/java/me/shedaniel/rei/api/client/gui/widgets/Widgets.java b/api/src/main/java/me/shedaniel/rei/api/client/gui/widgets/Widgets.java index fee50c9d5..9dbeb363c 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/gui/widgets/Widgets.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/gui/widgets/Widgets.java @@ -24,9 +24,7 @@ package me.shedaniel.rei.api.client.gui.widgets; import com.google.common.collect.AbstractIterator; -import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Matrix4f; -import com.mojang.math.Vector4f; import me.shedaniel.math.Dimension; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; @@ -37,13 +35,13 @@ import me.shedaniel.rei.impl.ClientInternals; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiComponent; import net.minecraft.client.gui.components.events.ContainerEventHandler; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.resources.sounds.SimpleSoundInstance; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvents; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -60,8 +58,51 @@ public final class Widgets { return ClientInternals.getWidgetsProvider().createDrawableWidget(drawable); } + public static WidgetWithBounds withTooltip(WidgetWithBounds widget, Component... texts) { + return withTooltip(widget, Arrays.asList(texts)); + } + + public static WidgetWithBounds withTooltip(WidgetWithBounds widget, Collection texts) { + return withBounds(concat( + widget, + createTooltip(widget::getBounds, texts) + ), widget::getBounds); + } + + public static Widget createTooltip(Rectangle bounds, Component... texts) { + return createTooltip(() -> bounds, Arrays.asList(texts)); + } + + public static Widget createTooltip(Rectangle bounds, Collection texts) { + return createTooltip(() -> bounds, texts); + } + + public static Widget createTooltip(Supplier bounds, Component... texts) { + return createTooltip(bounds, Arrays.asList(texts)); + } + + public static Widget createTooltip(Supplier bounds, Collection texts) { + return createTooltip(mouse -> { + if (bounds.get().contains(mouse)) { + return Tooltip.create(mouse, texts); + } else { + return null; + } + }); + } + + public static Widget createTooltip(Function tooltipSupplier) { + return createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> { + Point mouse = new Point(mouseX, mouseY); + Tooltip tooltip = tooltipSupplier.apply(mouse); + if (tooltip != null) { + tooltip.queue(); + } + }); + } + public static Widget wrapVanillaWidget(GuiEventListener element) { - return new VanillaWrappedWidget(element); + return ClientInternals.getWidgetsProvider().wrapVanillaWidget(element); } public static WidgetWithBounds withTranslate(Widget widget, double x, double y, double z) { @@ -69,119 +110,16 @@ public final class Widgets { } public static WidgetWithBounds withTranslate(Widget widget, Matrix4f translate) { - WidgetWithBounds widgetWithBounds = wrapWidgetWithBounds(widget); - return new WidgetWithBoundsWithTranslate(widgetWithBounds, () -> translate); + return withTranslate(widget, () -> translate); } public static WidgetWithBounds withTranslate(T widget, Function translate) { - WidgetWithBounds widgetWithBounds = wrapWidgetWithBounds(widget); - return new WidgetWithBoundsWithTranslate(widgetWithBounds, () -> translate.apply(widget)); + return withTranslate(widget, () -> translate.apply(widget)); } public static WidgetWithBounds withTranslate(Widget widget, Supplier translate) { WidgetWithBounds widgetWithBounds = wrapWidgetWithBounds(widget); - return new WidgetWithBoundsWithTranslate(widgetWithBounds, translate); - } - - private static class WidgetWithBoundsWithTranslate extends DelegateWidget { - private final Supplier translate; - - private WidgetWithBoundsWithTranslate(WidgetWithBounds widget, Supplier translate) { - super(widget); - this.translate = translate; - } - - @Override - public void render(PoseStack poseStack, int i, int j, float f) { - poseStack.pushPose(); - poseStack.last().pose().multiply(translate.get()); - Vector4f mouse = transformMouse(i, j); - super.render(poseStack, (int) mouse.x(), (int) mouse.y(), f); - poseStack.popPose(); - } - - private Vector4f transformMouse(double mouseX, double mouseY) { - Vector4f mouse = new Vector4f((float) mouseX, (float) mouseY, 0, 1); - mouse.transform(translate.get()); - return mouse; - } - - @Override - public boolean containsMouse(double mouseX, double mouseY) { - Vector4f mouse = transformMouse(mouseX, mouseY); - return super.containsMouse(mouse.x(), mouse.y()); - } - - @Override - public boolean mouseClicked(double d, double e, int i) { - Vector4f mouse = transformMouse(d, e); - return super.mouseClicked(mouse.x(), mouse.y(), i); - } - - @Override - public boolean mouseReleased(double d, double e, int i) { - Vector4f mouse = transformMouse(d, e); - return super.mouseReleased(mouse.x(), mouse.y(), i); - } - - @Override - public boolean mouseDragged(double d, double e, int i, double f, double g) { - Vector4f mouse = transformMouse(d, e); - return super.mouseDragged(mouse.x(), mouse.y(), i, f, g); - } - - @Override - public boolean mouseScrolled(double d, double e, double f) { - Vector4f mouse = transformMouse(d, e); - return super.mouseScrolled(mouse.x(), mouse.y(), f); - } - } - - private static class VanillaWrappedWidget extends Widget { - private GuiEventListener element; - - public VanillaWrappedWidget(GuiEventListener element) { - this.element = Objects.requireNonNull(element); - setFocused(element); - } - - @Override - public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { - if (element instanceof GuiComponent component) - component.setBlitOffset(getZ()); - if (element instanceof net.minecraft.client.gui.components.Widget widget) - widget.render(matrices, mouseX, mouseY, delta); - } - - @Override - public List children() { - return Collections.singletonList(element); - } - - @Nullable - @Override - public GuiEventListener getFocused() { - return element; - } - - @Override - public void setFocused(@Nullable GuiEventListener guiEventListener) { - if (guiEventListener == element) { - super.setFocused(element); - } else if (element instanceof ContainerEventHandler handler) { - handler.setFocused(guiEventListener); - } - } - - @Override - public boolean isDragging() { - return true; - } - - @Override - public boolean containsMouse(double mouseX, double mouseY) { - return element.isMouseOver(mouseX, mouseY); - } + return ClientInternals.getWidgetsProvider().withTranslate(widgetWithBounds, translate); } public static WidgetWithBounds wrapRenderer(Rectangle bounds, Renderer renderer) { @@ -191,18 +129,45 @@ public final class Widgets { public static WidgetWithBounds wrapRenderer(Supplier bounds, Renderer renderer) { if (renderer instanceof Widget widget) return wrapWidgetWithBoundsSupplier(widget, bounds); - return new RendererWrappedWidget(renderer, bounds); + return ClientInternals.getWidgetsProvider().wrapRenderer(bounds, renderer); } + /** + * @deprecated Use {@link #withBounds(Widget)} instead. + */ + @Deprecated(forRemoval = true) + @ApiStatus.ScheduledForRemoval public static WidgetWithBounds wrapWidgetWithBounds(Widget widget) { - return wrapWidgetWithBounds(widget, null); + return withBounds(widget); } + /** + * @deprecated Use {@link #withBounds(Widget, Rectangle)} instead. + */ + @Deprecated(forRemoval = true) + @ApiStatus.ScheduledForRemoval public static WidgetWithBounds wrapWidgetWithBounds(Widget widget, Rectangle bounds) { - return wrapWidgetWithBoundsSupplier(widget, bounds == null ? null : () -> bounds); + return withBounds(widget, bounds); } + /** + * @deprecated Use {@link #withBounds(Widget, Supplier)} instead. + */ + @Deprecated(forRemoval = true) + @ApiStatus.ScheduledForRemoval public static WidgetWithBounds wrapWidgetWithBoundsSupplier(Widget widget, Supplier bounds) { + return withBounds(widget, bounds); + } + + public static WidgetWithBounds withBounds(Widget widget) { + return wrapWidgetWithBounds(widget, null); + } + + public static WidgetWithBounds withBounds(Widget widget, Rectangle bounds) { + return wrapWidgetWithBoundsSupplier(widget, bounds == null ? null : () -> bounds); + } + + public static WidgetWithBounds withBounds(Widget widget, Supplier bounds) { if (widget instanceof WidgetWithBounds withBounds) return withBounds; if (bounds == null) @@ -210,57 +175,6 @@ public final class Widgets { return new DelegateWidgetWithBounds(widget, bounds); } - private static class RendererWrappedWidget extends WidgetWithBounds { - private final Renderer renderer; - private final Supplier bounds; - - public RendererWrappedWidget(Renderer renderer, Supplier bounds) { - this.renderer = Objects.requireNonNull(renderer); - this.bounds = Objects.requireNonNull(bounds); - } - - @Override - public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { - renderer.render(matrices, getBounds(), mouseX, mouseY, delta); - } - - @Override - public List children() { - if (renderer instanceof GuiEventListener listener) - return Collections.singletonList(listener); - return Collections.emptyList(); - } - - @Override - public void setZ(int z) { - renderer.setZ(z); - } - - @Override - public int getZ() { - return renderer.getZ(); - } - - @Override - public Rectangle getBounds() { - return bounds.get(); - } - } - - private static class DelegateWidgetWithBounds extends DelegateWidget { - private final Supplier bounds; - - public DelegateWidgetWithBounds(Widget widget, Supplier bounds) { - super(widget); - this.bounds = bounds; - } - - @Override - public Rectangle getBounds() { - return bounds.get(); - } - } - public static Widget createTexturedWidget(ResourceLocation identifier, Rectangle bounds) { return createTexturedWidget(identifier, bounds, 0, 0); } @@ -357,6 +271,14 @@ public final class Widgets { return createSlotBase(rectangle).color(color); } + public static Widget createShapelessIcon(Rectangle rectangle) { + return createShapelessIcon(new Point(rectangle.getMaxX() - 4, rectangle.y + 4)); + } + + public static Widget createShapelessIcon(Point topRightPos) { + return ClientInternals.getWidgetsProvider().createShapelessIcon(topRightPos); + } + public static Slot createSlot(Point point) { return ClientInternals.getWidgetsProvider().createSlot(point); } @@ -373,6 +295,14 @@ public final class Widgets { Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F)); } + public static Widget concat(Widget... widgets) { + return concat(Arrays.asList(widgets)); + } + + public static Widget concat(List widgets) { + return ClientInternals.getWidgetsProvider().concatWidgets(widgets); + } + public static Iterable walk(Iterable listeners, Predicate predicate) { return () -> new AbstractIterator() { Stack> stack; diff --git a/api/src/main/java/me/shedaniel/rei/impl/ClientInternals.java b/api/src/main/java/me/shedaniel/rei/impl/ClientInternals.java index 755ab943a..4341771d1 100644 --- a/api/src/main/java/me/shedaniel/rei/impl/ClientInternals.java +++ b/api/src/main/java/me/shedaniel/rei/impl/ClientInternals.java @@ -23,6 +23,7 @@ package me.shedaniel.rei.impl; +import com.mojang.math.Matrix4f; import com.mojang.serialization.DataResult; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; @@ -30,6 +31,7 @@ import me.shedaniel.rei.api.client.ClientHelper; import me.shedaniel.rei.api.client.entry.renderer.EntryRenderer; import me.shedaniel.rei.api.client.favorites.FavoriteEntry; import me.shedaniel.rei.api.client.gui.DrawableConsumer; +import me.shedaniel.rei.api.client.gui.Renderer; import me.shedaniel.rei.api.client.gui.widgets.*; import me.shedaniel.rei.api.client.plugins.REIClientPlugin; import me.shedaniel.rei.api.client.registry.screen.ClickArea; @@ -37,6 +39,7 @@ import me.shedaniel.rei.api.client.view.ViewSearchBuilder; import me.shedaniel.rei.api.common.plugins.PluginManager; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; @@ -155,6 +158,12 @@ public final class ClientInternals { public interface WidgetsProvider { boolean isRenderingPanel(Panel panel); + Widget wrapVanillaWidget(GuiEventListener element); + + WidgetWithBounds wrapRenderer(Supplier bounds, Renderer renderer); + + WidgetWithBounds withTranslate(WidgetWithBounds widget, Supplier translate); + Widget createDrawableWidget(DrawableConsumer drawable); Slot createSlot(Point point); @@ -174,5 +183,9 @@ public final class ClientInternals { DrawableConsumer createTexturedConsumer(ResourceLocation texture, int x, int y, int width, int height, float u, float v, int uWidth, int vHeight, int textureWidth, int textureHeight); DrawableConsumer createFillRectangleConsumer(Rectangle rectangle, int color); + + Widget createShapelessIcon(Point point); + + Widget concatWidgets(List widgets); } } diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/DefaultCraftingCategory.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/DefaultCraftingCategory.java index f4a4d0ca6..55f0ba48a 100644 --- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/DefaultCraftingCategory.java +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/DefaultCraftingCategory.java @@ -81,6 +81,9 @@ public class DefaultCraftingCategory implements DisplayCategory> extends BasicD return list; } + public boolean isShapeless() { + return false; + } + public static int getSlotWithSize(DefaultCraftingDisplay display, int index, int craftingGridWidth) { return getSlotWithSize(display.getInputWidth(), index, craftingGridWidth); } diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/crafting/DefaultShapelessDisplay.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/crafting/DefaultShapelessDisplay.java index 502c5c61b..8f500bfb9 100644 --- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/crafting/DefaultShapelessDisplay.java +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/crafting/DefaultShapelessDisplay.java @@ -61,4 +61,9 @@ public class DefaultShapelessDisplay extends DefaultCraftingDisplay translate; + + public DelegateWidgetWithTranslate(WidgetWithBounds widget, Supplier translate) { + super(widget); + this.translate = translate; + } + + @Override + public void render(PoseStack poseStack, int i, int j, float f) { + poseStack.pushPose(); + poseStack.last().pose().multiply(translate.get()); + Vector4f mouse = transformMouse(i, j); + super.render(poseStack, (int) mouse.x(), (int) mouse.y(), f); + poseStack.popPose(); + } + + private Vector4f transformMouse(double mouseX, double mouseY) { + Vector4f mouse = new Vector4f((float) mouseX, (float) mouseY, 0, 1); + mouse.transform(translate.get()); + return mouse; + } + + @Override + public boolean containsMouse(double mouseX, double mouseY) { + Vector4f mouse = transformMouse(mouseX, mouseY); + return super.containsMouse(mouse.x(), mouse.y()); + } + + @Override + public boolean mouseClicked(double d, double e, int i) { + Vector4f mouse = transformMouse(d, e); + return super.mouseClicked(mouse.x(), mouse.y(), i); + } + + @Override + public boolean mouseReleased(double d, double e, int i) { + Vector4f mouse = transformMouse(d, e); + return super.mouseReleased(mouse.x(), mouse.y(), i); + } + + @Override + public boolean mouseDragged(double d, double e, int i, double f, double g) { + Vector4f mouse = transformMouse(d, e); + return super.mouseDragged(mouse.x(), mouse.y(), i, f, g); + } + + @Override + public boolean mouseScrolled(double d, double e, double f) { + Vector4f mouse = transformMouse(d, e); + return super.mouseScrolled(mouse.x(), mouse.y(), f); + } +} \ No newline at end of file diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/InternalWidgets.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/InternalWidgets.java index e39b48fc5..f757bf9ad 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/InternalWidgets.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/InternalWidgets.java @@ -23,13 +23,14 @@ package me.shedaniel.rei.impl.client.gui.widget; -import com.google.common.collect.Lists; import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Matrix4f; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.math.impl.PointHelper; import me.shedaniel.rei.api.client.config.ConfigObject; import me.shedaniel.rei.api.client.gui.DrawableConsumer; +import me.shedaniel.rei.api.client.gui.Renderer; import me.shedaniel.rei.api.client.gui.widgets.*; import me.shedaniel.rei.api.client.registry.display.DisplayCategory; import me.shedaniel.rei.api.common.display.Display; @@ -44,12 +45,12 @@ import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.resources.language.I18n; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.FormattedText; +import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.ApiStatus; import java.util.Collection; import java.util.List; -import java.util.Objects; import java.util.function.Supplier; @ApiStatus.Internal @@ -141,34 +142,8 @@ public final class InternalWidgets { return new MergedWidget(widget2, widget1); } - private static class MergedWidget extends Widget { - private final List widgets; - - public MergedWidget(Widget widget1, Widget widget2) { - this.widgets = Lists.newArrayList(Objects.requireNonNull(widget1), Objects.requireNonNull(widget2)); - } - - @Override - public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { - for (Widget widget : widgets) { - widget.setZ(getZ()); - widget.render(matrices, mouseX, mouseY, delta); - } - } - - @Override - public List children() { - return widgets; - } - - @Override - public boolean mouseScrolled(double mouseX, double mouseY, double amount) { - for (Widget widget : this.widgets) { - if (widget.mouseScrolled(mouseX, mouseY, amount)) - return true; - } - return false; - } + public static Widget concatWidgets(List widgets) { + return new MergedWidget(widgets); } private static class LateRenderableWidget extends DelegateWidget implements LateRenderable { @@ -187,18 +162,34 @@ public final class InternalWidgets { return PanelWidget.isRendering(panel); } + @Override + public Widget wrapVanillaWidget(GuiEventListener element) { + if (element instanceof Widget) return (Widget) element; + return new VanillaWrappedWidget(element); + } + + @Override + public WidgetWithBounds wrapRenderer(Supplier bounds, Renderer renderer) { + return new RendererWrappedWidget(renderer, bounds); + } + + @Override + public WidgetWithBounds withTranslate(WidgetWithBounds widget, Supplier translate) { + return new DelegateWidgetWithTranslate(widget, translate); + } + @Override public Widget createDrawableWidget(DrawableConsumer drawable) { return new DrawableWidget(drawable); } @Override - public me.shedaniel.rei.api.client.gui.widgets.Slot createSlot(Point point) { + public Slot createSlot(Point point) { return new EntryWidget(point); } @Override - public me.shedaniel.rei.api.client.gui.widgets.Slot createSlot(Rectangle bounds) { + public Slot createSlot(Rectangle bounds) { return new EntryWidget(bounds); } @@ -236,5 +227,33 @@ public final class InternalWidgets { public DrawableConsumer createFillRectangleConsumer(Rectangle rectangle, int color) { return new FillRectangleDrawableConsumer(rectangle, color); } + + @Override + public Widget createShapelessIcon(Point point) { + int magnification; + double scale = Minecraft.getInstance().getWindow().getGuiScale(); + if (scale >= 1 && scale <= 4 && scale == Math.floor(scale)) { + magnification = (int) scale; + } else if (scale > 4 && scale == Math.floor(scale)) { + magnification = 1; + for (int i = 4; i >= 1; i--) { + if (scale % i == 0) { + magnification = i; + break; + } + } + } else { + magnification = 4; + } + Rectangle bounds = new Rectangle(point.getX() - 9, point.getY() + 1, 8, 8); + Widget widget = Widgets.createTexturedWidget(new ResourceLocation("roughlyenoughitems:textures/gui/shapeless_icon_" + magnification + "x.png"), bounds.getX(), bounds.getY(), 0, 0, bounds.getWidth(), bounds.getHeight(), 1, 1, 1, 1); + return Widgets.withTooltip(Widgets.withBounds(widget, bounds), + new TranslatableComponent("text.rei.shapeless")); + } + + @Override + public Widget concatWidgets(List widgets) { + return InternalWidgets.concatWidgets(widgets); + } } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/MergedWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/MergedWidget.java new file mode 100644 index 000000000..e419a7db7 --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/MergedWidget.java @@ -0,0 +1,66 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.impl.client.gui.widget; + +import com.google.common.collect.Lists; +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.rei.api.client.gui.widgets.Widget; +import net.minecraft.client.gui.components.events.GuiEventListener; + +import java.util.List; +import java.util.Objects; + +public class MergedWidget extends Widget { + private final List widgets; + + public MergedWidget(Widget widget1, Widget widget2) { + this.widgets = Lists.newArrayList(Objects.requireNonNull(widget1), Objects.requireNonNull(widget2)); + } + + public MergedWidget(List widgets) { + this.widgets = widgets; + } + + @Override + public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { + for (Widget widget : widgets) { + widget.setZ(getZ()); + widget.render(matrices, mouseX, mouseY, delta); + } + } + + @Override + public List children() { + return widgets; + } + + @Override + public boolean mouseScrolled(double mouseX, double mouseY, double amount) { + for (Widget widget : this.widgets) { + if (widget.mouseScrolled(mouseX, mouseY, amount)) + return true; + } + return false; + } +} \ No newline at end of file diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/RendererWrappedWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/RendererWrappedWidget.java new file mode 100644 index 000000000..97d9f3e3d --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/RendererWrappedWidget.java @@ -0,0 +1,72 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.impl.client.gui.widget; + +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.Renderer; +import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds; +import net.minecraft.client.gui.components.events.GuiEventListener; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.function.Supplier; + +public class RendererWrappedWidget extends WidgetWithBounds { + private final Renderer renderer; + private final Supplier bounds; + + public RendererWrappedWidget(Renderer renderer, Supplier bounds) { + this.renderer = Objects.requireNonNull(renderer); + this.bounds = Objects.requireNonNull(bounds); + } + + @Override + public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { + renderer.render(matrices, getBounds(), mouseX, mouseY, delta); + } + + @Override + public List children() { + if (renderer instanceof GuiEventListener listener) + return Collections.singletonList(listener); + return Collections.emptyList(); + } + + @Override + public void setZ(int z) { + renderer.setZ(z); + } + + @Override + public int getZ() { + return renderer.getZ(); + } + + @Override + public Rectangle getBounds() { + return bounds.get(); + } +} \ No newline at end of file diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/VanillaWrappedWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/VanillaWrappedWidget.java new file mode 100644 index 000000000..2aacd5e73 --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/VanillaWrappedWidget.java @@ -0,0 +1,82 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.impl.client.gui.widget; + +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.rei.api.client.gui.widgets.Widget; +import net.minecraft.client.gui.GuiComponent; +import net.minecraft.client.gui.components.events.ContainerEventHandler; +import net.minecraft.client.gui.components.events.GuiEventListener; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +public class VanillaWrappedWidget extends Widget { + private GuiEventListener element; + + public VanillaWrappedWidget(GuiEventListener element) { + this.element = Objects.requireNonNull(element); + setFocused(element); + } + + @Override + public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { + if (element instanceof GuiComponent component) + component.setBlitOffset(getZ()); + if (element instanceof net.minecraft.client.gui.components.Widget widget) + widget.render(matrices, mouseX, mouseY, delta); + } + + @Override + public List children() { + return Collections.singletonList(element); + } + + @Nullable + @Override + public GuiEventListener getFocused() { + return element; + } + + @Override + public void setFocused(@Nullable GuiEventListener guiEventListener) { + if (guiEventListener == element) { + super.setFocused(element); + } else if (element instanceof ContainerEventHandler handler) { + handler.setFocused(guiEventListener); + } + } + + @Override + public boolean isDragging() { + return true; + } + + @Override + public boolean containsMouse(double mouseX, double mouseY) { + return element.isMouseOver(mouseX, mouseY); + } +} \ No newline at end of file diff --git a/runtime/src/main/resources/assets/roughlyenoughitems/lang/de_de.json b/runtime/src/main/resources/assets/roughlyenoughitems/lang/de_de.json index 9ef6b85dd..be57c125f 100644 --- a/runtime/src/main/resources/assets/roughlyenoughitems/lang/de_de.json +++ b/runtime/src/main/resources/assets/roughlyenoughitems/lang/de_de.json @@ -9,10 +9,27 @@ "text.rei.search.field.suggestion": "Suche...", "text.rei.feedback": "Möchtest du dem REI Entwickler dein Feedback geben? %s um dein Feedback einzureichen!", "text.rei.feedback.link": "Klicke hier um das Google-Form zu besuchen", + "text.rei.support.me": "Unterstütze mich, um REI weiter zu verbessern!", + "text.rei.support.me.desc": "Als Patreon Unterstützer von REI kannst du die neueste Version von REI für Minecraft Snapshots verwenden.\nAlternativ kannst du mich auch finanziell unterstützen, indem du einen BisectHosting Server mietst.\n\n%s\n%s", + "text.rei.support.me.patreon": "Spenden auf Patreon", + "text.rei.support.me.bisect": "Code SHEDANIEL auf BisectHosting verwenden", "text.rei.not.fully.initialized": "REI noch nicht vollständig initialisiert!", "text.rei.not.fully.initialized.tooltip": "Fehlende Stufen: %s\nFalls dies nicht weggeht,\nversuche mit den Logs nach Unterstützung zu suchen!", "text.rei.inventory.highlighting.enabled": "Inventarhervorhebung an", "text.rei.inventory.highlighting.enabled.tooltip": "Dies macht Slots, die nicht mit dem\nSuchfilter übereinstimmen grau.\nDoppelklicke die Suchleiste, um diesen Modus an- und auszuschalten.", + "text.rei.caching.search": "REI Caching Suchergebnisse...", + "text.rei.caching.search.step": "Schritt %d/%d (%s%%):", + "text.rei.config.menu.dark_theme": "Dunkles Design", + "text.rei.config.menu.craftable_filter": "Filter für Herstellbare Gegenstände", + "text.rei.config.menu.display": "Anzeigeeinstellungen", + "text.rei.config.menu.display.remove_recipe_book": "Rezeptbuch entfernen", + "text.rei.config.menu.display.left_side_mob_effects": "Linke Seite Mob-Effekte", + "text.rei.config.menu.display.left_side_panel": "Linke Seitenleiste", + "text.rei.config.menu.display.scrolling_side_panel": "Durchscrollbarer Seitenbereich", + "text.rei.config.menu.display.caching_entry_rendering": "Schnelleres Eintrags-Rendering", + "text.rei.config.menu.display.side_search_field": "Suchfeld", + "text.rei.config.menu.display.syntax_highlighting": "Syntax-Hervorhebung", + "text.rei.config.menu.config": "Weitere Optionen...", "category.rei.crafting": "Herstellen", "category.rei.smelting": "Schmelzen", "category.rei.smelting.fuel": "Brennstoff", @@ -39,6 +56,10 @@ "category.rei.beacon_payment": "Leuchtfeuerkosten", "category.rei.tilling": "Aufteilung", "category.rei.pathing": "Pfad", + "category.rei.waxing": "Wachsen", + "category.rei.wax_scraping": "Wachs abscharben", + "category.rei.oxidizing": "Oxidation", + "category.rei.oxidation_scraping": "Oxidationsabakratzung", "category.rei.information": "Information", "text.rei.composting.chance": "§e%d%% Chance", "text.rei.composting.page": "Seite %d", @@ -47,6 +68,7 @@ "text.rei.cheat_items": "[{item_name}] x{item_count} {player_name} gegeben.", "text.rei.failed_cheat_items": "§cItems geben fehlgeschlagen.", "text.rei.too_long_nbt": "§cGegenstand NBT ist zu lang, um im Multiplayer angewendet zu werden.", + "text.rei.tag_match": "Akzeptierter Tag: #%s", "text.rei.performance": "Leistungsanalyse", "ordering.rei.ascending": "Aufsteigend", "ordering.rei.descending": "Absteigend", @@ -54,12 +76,14 @@ "ordering.rei.name": "Name", "ordering.rei.item_groups": "Itemgruppen", "text.auto_craft.move_items": "Items bewegen", + "text.auto_craft.move_items.tooltip": "Strg-Klick zum Verschieben von Elementen", "text.auto_craft.move_items.yog": "Generiert NullPointerException!!", "error.rei.transfer.too_small": "Gegenstände können nicht in ein %dx%d-Raster verschoben werden.", "error.rei.not.on.server": "REI ist nicht auf dem Server installiert.", "error.rei.not.enough.materials": "Nicht genügend Materialien.", "error.rei.internal.error": "Interner Fehler: %s", "error.rei.recipe.not.unlocked": "Rezept nicht im Rezeptbuch freigeschaltet.", + "error.rei.not.supported.move.items": "Verschieben von Elementen wird mit diesem Rezept und diesem Container nicht unterstützt.", "error.rei.no.handlers.applicable": "Keine Handler anwendbar.", "error.rei.multi.errors": "Mehrere Fehler:", "rei.rei.no.slot.in.inv": "Kann keinen Platz für Gegenstand im Inventar finden", @@ -77,7 +101,14 @@ "text.rei.gamemode_button.tooltip.entry": "zu %s wechseln", "text.rei.weather_button.tooltip.dropdown": "Wetter ändern: Auswahl", "text.rei.weather_button.tooltip.entry": "zu %s wechseln", + "text.rei.time_button.tooltip.dropdown": "Wetter ändern: Auswahl", + "text.rei.time_button.tooltip.entry": "zu %s wechseln", + "text.rei.time_button.name.morn": "Morgen", + "text.rei.time_button.name.noon": "Mittag", + "text.rei.time_button.name.evening": "Abend", + "text.rei.time_button.name.night": "Nacht", "text.rei.reload_config": "Plugins neu laden", + "text.rei.reload_search": "Suche neu laden", "text.rei.config.is.reloading": "Plugins werden neu geladen!", "text.rei.enabled": "Ja", "text.rei.disabled": "Nein", @@ -112,8 +143,15 @@ "text.rei.tiny_potato": "Kleine Kartöffelchen", "text.rei.add_favorite_widget": "Hinzufügen...", "text.rei.dispose_here": "Hier verwerfen", + "text.rei.crash.title": "REI ist abgestürzt!", + "text.rei.crash.description": "§cRoughly Enough Items hat gerade einen Absturz während \"%s\" erlebt.\n\n§fDetails des Absturzes werden unten angezeigt. Bitte identifiziere die Modifikation, die den Absturz verursacht hat, und melde sie an den Mod-Autor, neben dem unten angegebenen Absturzprotokoll.\n\nWenn Sie glauben, dass dieser Absturz durch einen Fehler in Roughly Enough Items verursacht wird, melden Sie ihn bitte an unseren Issue-Tracker.\n\n§6Vielen Dank für deine Hilfe!\n", + "text.rei.crash.crash_report": "Absturzbericht öffnen", + "text.rei.changelog.title": "REI Änderungsliste", + "text.rei.changelog.error.missingChangelogFile": "Fehlende Änderungsprotokolldatei!", + "text.rei.changelog.error.failedToReadChangelogFile": "Fehler beim Lesen der Änderungsprotokolldatei!", "favorite.section.gamemode": "Spielmodus", "favorite.section.weather": "Wetter", + "favorite.section.time": "Zeit", "tooltip.rei.fluid_amount": "§7%d Einheit", "tooltip.rei.fluid_amount.forge": "§7%d mB", "tooltip.rei.drag_to_add_favorites": "§7Ziehe dies zu deinen Favoriten!", @@ -130,6 +168,7 @@ "config.roughlyenoughitems.functionality": "Funktionalität", "config.roughlyenoughitems.advanced": "Erweitert", "config.roughlyenoughitems.cheating": "Schummeln:", + "config.roughlyenoughitems.cheating.when_creative": "Im Kreativmodus", "config.roughlyenoughitems.favoritesEnabled": "Favoriten aktiviert:", "config.roughlyenoughitems.keyBindings": "Tastaturbelegungen", "config.roughlyenoughitems.keyBindings.recipeKeybind": "Zeige Rezept:", @@ -169,6 +208,10 @@ "config.roughlyenoughitems.layout.configButtonLocation.upper": "Obere", "config.roughlyenoughitems.layout.configButtonLocation.lower": "Untere", "config.roughlyenoughitems.layout.mergeDisplayUnderOne": "Vereine alle Displays mit demselben Inhalt", + "config.roughlyenoughitems.layout.favoriteAddWidgetMode": "Favoriten Widget-Schaltfläche hinzufügen:", + "config.roughlyenoughitems.layout.favoriteAddWidgetMode.always_invisible": "Immer unsichtbar", + "config.roughlyenoughitems.layout.favoriteAddWidgetMode.auto_hide": "Automatisch ausblenden", + "config.roughlyenoughitems.layout.favoriteAddWidgetMode.always_visible": "Immer sichtbar", "config.roughlyenoughitems.filteredEntries.selectAll": "Alles Auswählen", "config.roughlyenoughitems.filteredEntries.selectNone": "Alle abwählen", "config.roughlyenoughitems.filteredEntries.hide": "Auswahl verstecken", @@ -210,6 +253,9 @@ "config.roughlyenoughitems.disableRecipeBook": "Vanilla Rezeptbuch:", "config.roughlyenoughitems.disableRecipeBook.boolean.true": "§cNein", "config.roughlyenoughitems.disableRecipeBook.boolean.false": "§aJa", + "config.roughlyenoughitems.leftSideMobEffects": "Position der Mob-Effekte:", + "config.roughlyenoughitems.leftSideMobEffects.boolean.true": "Links", + "config.roughlyenoughitems.leftSideMobEffects.boolean.false": "Rechts (Vanilla)", "config.roughlyenoughitems.fixTabCloseContainer": "Korrigier den Vanilla Tab Container (wenn das Rezeptbuch deaktiviert ist):", "config.roughlyenoughitems.lighterButtonHover": "Helles Button-Hovern:", "config.roughlyenoughitems.layout.enableCraftableOnlyButton": "Filter für Herstellbare Gegenstände:", @@ -225,6 +271,8 @@ "config.roughlyenoughitems.layout.entryPanelOrdering": "Reihenfolge der Itemlisten:", "config.roughlyenoughitems.list_ordering_button": "%s [%s]", "config.roughlyenoughitems.miscellaneous.newFastEntryRendering": "Schnelleres Eintrags-Rendering:", + "config.roughlyenoughitems.miscellaneous.cachingFastEntryRendering": "Schnelleres Eintrags-Rendering:", + "config.roughlyenoughitems.miscellaneous.cachingFastEntryRendering.@PrefixText": "Diese Option verbessert die Leistung bei der Darstellung von Einträgen bis zu 5x, mit durchschnittlich 2. x Leistungssteigerung. Dies wird jedoch die Verzauberungsbrille und animierte Texturen zerstören/verbuggen.", "config.roughlyenoughitems.itemCheatingMode": "Anzahl der Gegenstände beim Cheaten:", "config.roughlyenoughitems.itemCheatingMode.rei_like": "Normal", "config.roughlyenoughitems.itemCheatingMode.jei_like": "Umgekehrt", @@ -248,6 +296,8 @@ "config.roughlyenoughitems.syntaxHighlightingMode.plain_underscored": "Normal unterstrichen", "config.roughlyenoughitems.syntaxHighlightingMode.colorful": "Farbig", "config.roughlyenoughitems.syntaxHighlightingMode.colorful_underscored": "Farbig unterstrichen", + "config.roughlyenoughitems.isFocusModeZoomed": "Autofokus-Modus", + "config.roughlyenoughitems.isFocusModeZoomed.boolean.true": "Gezoomt", "config.roughlyenoughitems.filteringScreen": "Benutzerdefinierte Filter", "config.roughlyenoughitems.filteringRulesScreen": "Benutzerdefinierte Filterregeln", "config.roughlyenoughitems.filteringRulesScreen.new": "Filterregel erstellen", diff --git a/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json b/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json index 6f8b677f0..2817ab195 100755 --- a/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json +++ b/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json @@ -70,13 +70,14 @@ "text.rei.too_long_nbt": "§cItem NBT is too long to be applied in multiplayer.", "text.rei.tag_match": "Accepts Tag: #%s", "text.rei.performance": "Performance Analysis", + "text.rei.shapeless": "Shapeless", "ordering.rei.ascending": "Ascending", "ordering.rei.descending": "Descending", "ordering.rei.registry": "Registry", "ordering.rei.name": "Name", "ordering.rei.item_groups": "Item Groups", "text.auto_craft.move_items": "Move Items", - "text.auto_craft.move_items.tooltip": "Ctrl-Click to Move Items", + "text.auto_craft.move_items.tooltip": "Ctrl-Click to Quick Craft", "text.auto_craft.move_items.yog": "Generate NullPointerException!!", "error.rei.transfer.too_small": "Unable to move items to a %dx%d grid.", "error.rei.not.on.server": "REI is not on the server.", diff --git a/runtime/src/main/resources/assets/roughlyenoughitems/lang/pt_br.json b/runtime/src/main/resources/assets/roughlyenoughitems/lang/pt_br.json index 0025052fb..35c9550e8 100644 --- a/runtime/src/main/resources/assets/roughlyenoughitems/lang/pt_br.json +++ b/runtime/src/main/resources/assets/roughlyenoughitems/lang/pt_br.json @@ -7,13 +7,17 @@ "text.rei.cheating_limited_creative_enabled": "§aAtivar trapaças (modo Criativo)", "text.rei.no_permission_cheat": "Você precisa ser um operador para obter itens", "text.rei.search.field.suggestion": "Buscar...", - "text.rei.feedback": "Deseja enviar feedback ao desenvolvedor do REI? %s para enviá-lo!", + "text.rei.feedback": "Deseja enviar um feedback ao desenvolvedor do REI? %s para enviá-lo!", "text.rei.feedback.link": "Acesse o formulário de feedback", + "text.rei.support.me": "Apoie o REI para torná-lo ainda melhor!", + "text.rei.support.me.desc": "Como apoiador do REI no Patreon, você pode baixar a versão mais recente do REI para snapshots.\nVocê também pode me apoiar ao alugar um servidor na BisectHosting.", + "text.rei.support.me.patreon": "Apoie o REI no Patreon", + "text.rei.support.me.bisect": "Use o código SHEDANIEL na BisectHosting", "text.rei.not.fully.initialized": "O REI ainda não está completamente inicializado!", "text.rei.not.fully.initialized.tooltip": "Etapas restantes: %s\nSe isso continuar,\nverifique os registros!\n", "text.rei.inventory.highlighting.enabled": "Destaque de inventário ativado", "text.rei.inventory.highlighting.enabled.tooltip": "Os espaços não encontrados na busca\nficarão da cor cinza.\nClique duas vezes na barra de busca para ativar o modo.", - "text.rei.caching.search": "Memorizando busca...", + "text.rei.caching.search": "Memorizando busca do REI...", "text.rei.caching.search.step": "Passo %d/%d (%s%%):", "text.rei.config.menu.dark_theme": "Tema escuro", "text.rei.config.menu.craftable_filter": "Fabricáveis", @@ -59,8 +63,8 @@ "category.rei.information": "Informações", "text.rei.composting.chance": "§e%d%% de chances", "text.rei.composting.page": "Pág. %d", - "text.rei.config": "Definições", - "text.rei.config_tooltip": "Abrir menu de definições\n§7Shift + clique para alternar o modo trapaça", + "text.rei.config": "Ajustes", + "text.rei.config_tooltip": "Abrir menu de ajustes\n§7Shift + clique para alternar o modo trapaça", "text.rei.cheat_items": "{player_name} recebeu {item_count} unidade(s) de [{item_name}§f].", "text.rei.failed_cheat_items": "§cFalha ao obter itens.", "text.rei.too_long_nbt": "§cO NBT do item é longo demais para ser aplicado ao modo multijogador.", @@ -75,10 +79,10 @@ "text.auto_craft.move_items.tooltip": "Ctrl + clique para mover itens", "text.auto_craft.move_items.yog": "Gerar NullPointerException!", "error.rei.transfer.too_small": "Não é possível mover os itens para uma grade %dx%d.", - "error.rei.not.on.server": "O REI não está disponível no servidor.", + "error.rei.not.on.server": "O REI não está no servidor.", "error.rei.not.enough.materials": "Matéria-prima insuficiente.", "error.rei.internal.error": "Erro interno: %s", - "error.rei.recipe.not.unlocked": "Receita inacessível no livro de receitas.", + "error.rei.recipe.not.unlocked": "Receita inacessível no livro.", "error.rei.not.supported.move.items": "Não é possível mover itens com essa receita e contêiner.", "error.rei.no.handlers.applicable": "Processo indisponível.", "error.rei.multi.errors": "Vários erros:", @@ -97,13 +101,14 @@ "text.rei.gamemode_button.tooltip.entry": "Mudar para %s", "text.rei.weather_button.tooltip.dropdown": "Alterar tempo: Lista", "text.rei.weather_button.tooltip.entry": "Mudar para %s", + "text.rei.time_button.tooltip.entry": "Alterar para %s", "text.rei.time_button.name.morn": "Manhã", "text.rei.time_button.name.noon": "Meio-dia", "text.rei.time_button.name.evening": "Fim de tarde", "text.rei.time_button.name.night": "Noite", - "text.rei.reload_config": "Recarregar plug-ins", + "text.rei.reload_config": "Recarregar plugins", "text.rei.reload_search": "Recarregar busca", - "text.rei.config.is.reloading": "Recarregando plug-ins!", + "text.rei.config.is.reloading": "Recarregando plugins!", "text.rei.enabled": "Sim", "text.rei.disabled": "Não", "text.rei.short_gamemode.survival": "S", @@ -126,11 +131,11 @@ "text.rei.release_export": "Solte %s para exportar", "text.rei.recipe_id": "\n%sID: %s", "text.rei.recipe_screen_type.selection": "Selecionar estilo da tela de receita", - "text.rei.recipe_screen_type.selection.sub": "Você sempre pode editar essa opção no menu de definições.", + "text.rei.recipe_screen_type.selection.sub": "Você sempre pode editar essa opção no menu de ajustes.", "text.rei.jei_compat": "Camada de compatibilidade do JEI", "text.rei.jei_compat.false": "Camada de compatibilidade do JEI: Não", "text.rei.jei_compat.true": "Camada de compatibilidade do JEI: Sim", - "text.rei.jei_compat.sub": "Deseja ativar a camada de compatibilidade do JEI %s§7?\n§7Você pode carregar plug-ins do JEI pelas seguintes fontes:\n%s\n\n§7Lembre-se de que a compatibilidade do REI com o JEI não é perfeita.\n§cUSE POR SUA CONTA E RISCO!", + "text.rei.jei_compat.sub": "Deseja ativar a camada de compatibilidade do JEI %s§7?\n§7Você pode carregar plugins do JEI pelas seguintes fontes:\n%s\n\n§7Lembre-se de que a compatibilidade do REI com o JEI não é perfeita.\n§cUSE POR SUA CONTA E RISCO!", "text.rei.jei_compat.sub.stability": "§c§l(ALFA)", "text.rei.view_recipes_for": "Ver receitas para %s", "text.rei.subsets": "Subconjuntos", @@ -138,10 +143,11 @@ "text.rei.add_favorite_widget": "Adicionar...", "text.rei.dispose_here": "Deixe aqui", "text.rei.crash.title": "O REI parou de funcionar!", + "text.rei.crash.description": "§cO Roughly Enough Items parou de funcionar durante o evento \"%s\".\n\n§fVeja os detalhes abaixo. Identifique o mod que causou a parada e informe ao autor com o relatório de erro abaixo.\n\nSe você acha que a parada foi causada por um erro no Roughly Enough Items, informe-o no issue tracker.\n\n§6Obrigado!", "text.rei.crash.crash_report": "Abrir relatório de erro", - "text.rei.changelog.title": "Registro de alterações", + "text.rei.changelog.title": "Log de alterações do REI", "text.rei.changelog.error.missingChangelogFile": "Registro ausente!", - "text.rei.changelog.error.failedToReadChangelogFile": "Falha ao ler registro!", + "text.rei.changelog.error.failedToReadChangelogFile": "Falha ao ler o log!", "favorite.section.gamemode": "Modo de jogo", "favorite.section.weather": "Tempo", "tooltip.rei.fluid_amount": "§7%d unidade(s)", @@ -153,8 +159,8 @@ "msg.rei.exported_recipe.desc": "Verifique a pasta \"rei_exports\".", "subsets.rei.roughlyenoughitems.all_entries": "Todas", "subsets.rei.roughlyenoughitems.item_groups": "Guias do Criativo", - "_comment": "Descrições de definições", - "config.roughlyenoughitems.title": "Definições do Roughly Enough Items", + "_comment": "Descrição de ajustes", + "config.roughlyenoughitems.title": "Ajustes do Roughly Enough Items", "config.roughlyenoughitems.basics": "Básico", "config.roughlyenoughitems.appearance": "Estilo", "config.roughlyenoughitems.functionality": "Funções", @@ -176,8 +182,8 @@ "config.roughlyenoughitems.cheatingStyle": "Estilo de trapaça:", "config.roughlyenoughitems.cheatingStyle.grab": "Pegar", "config.roughlyenoughitems.cheatingStyle.give": "Dar", - "config.roughlyenoughitems.motion": "Definições de animações", - "config.roughlyenoughitems.motion.configScreenAnimation": "Animação da tela de def.:", + "config.roughlyenoughitems.motion": "Ajustes de animação", + "config.roughlyenoughitems.motion.configScreenAnimation": "Animação dos ajustes:", "config.roughlyenoughitems.motion.creditsScreenAnimation": "Animação da tela de créditos:", "config.roughlyenoughitems.motion.favoritesAnimation": "Favoritos animados:", "config.roughlyenoughitems.recipeScreenType": "Estilo da tela de receita:", @@ -196,10 +202,11 @@ "config.roughlyenoughitems.isSubsetsEnabled": "Ativar subconjuntos:", "config.roughlyenoughitems.allowInventoryHighlighting": "Destaque de inventário ativado:", "config.roughlyenoughitems.miscellaneous.renderEntryEnchantmentGlint": "Brilho do encantamento:", - "config.roughlyenoughitems.layout.configButtonLocation": "Posição dos botões de definições:", + "config.roughlyenoughitems.layout.configButtonLocation": "Posição dos botões de ajustes:", "config.roughlyenoughitems.layout.configButtonLocation.upper": "Superior", "config.roughlyenoughitems.layout.configButtonLocation.lower": "Inferior", "config.roughlyenoughitems.layout.mergeDisplayUnderOne": "Unir visores de conteúdo idêntico:", + "config.roughlyenoughitems.layout.favoriteAddWidgetMode": "Botão de widget dos favoritos:", "config.roughlyenoughitems.layout.favoriteAddWidgetMode.always_invisible": "Sempre invisível", "config.roughlyenoughitems.layout.favoriteAddWidgetMode.auto_hide": "Ocultar auto.", "config.roughlyenoughitems.layout.favoriteAddWidgetMode.always_visible": "Sempre visível", @@ -219,7 +226,7 @@ "config.roughlyenoughitems.recipeBorder.lighter": "Claro", "config.roughlyenoughitems.recipeBorder.default": "Padrão", "config.roughlyenoughitems.recipeBorder.none": "Não", - "config.roughlyenoughitems.layout.maxRecipesPerPage": "Máximo de receitas por página:", + "config.roughlyenoughitems.layout.maxRecipesPerPage": "Limite de receitas por página:", "config.roughlyenoughitems.layout.maxRecipesPageHeight": "Altura máxima da página de receitas:", "config.roughlyenoughitems.accessibility.displayPanelLocation": "Posição do painel de entradas:", "config.roughlyenoughitems.accessibility.displayPanelLocation.left": "Esquerdo", @@ -232,7 +239,7 @@ "config.roughlyenoughitems.search_mode.prefix": "Ao usar prefixo", "config.roughlyenoughitems.search_mode.never": "Sempre inativo", "config.roughlyenoughitems.layout.debugRenderTimeRequired": "Depuração do painel de entradas:", - "config.roughlyenoughitems.search.debugSearchTimeRequired": "Modo de busca por depuração:", + "config.roughlyenoughitems.search.debugSearchTimeRequired": "Busca por depuração:", "config.roughlyenoughitems.accessibility.resizeDynamically": "Escala dinâmica:", "config.roughlyenoughitems.layout.searchFieldLocation": "Posição do campo de busca:", "config.roughlyenoughitems.layout.searchFieldLocation.bottom_side": "Inferior esq./Direita", @@ -249,10 +256,10 @@ "config.roughlyenoughitems.leftSideMobEffects.boolean.false": "Direita (padrão)", "config.roughlyenoughitems.fixTabCloseContainer": "Corrigir contêiner de guias padrão (livro de receitas desativado):", "config.roughlyenoughitems.lighterButtonHover": "Cursor mínimo do botão:", - "config.roughlyenoughitems.layout.enableCraftableOnlyButton": "Filtro (fabricáveis):", + "config.roughlyenoughitems.layout.enableCraftableOnlyButton": "Filtro de fabricáveis:", "config.roughlyenoughitems.layout.showUtilsButtons": "Botões utilitários:", "config.roughlyenoughitems.commands.gamemodeCommand": "Comando do modo de jogo:", - "config.roughlyenoughitems.commands.giveCommand": "Comando give:", + "config.roughlyeno