aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorUnknown <shekwancheung0528@gmail.com>2019-01-10 16:33:18 +0800
committerUnknown <shekwancheung0528@gmail.com>2019-01-10 16:33:18 +0800
commit7b6c58c7db26747783aee7aff2eff87f08ecb8c3 (patch)
tree6a0e24aba2b869d18de65dd7dc1dcd8e78d4dcb2 /src/main
parent1b21d26487636e50d03979acd5ca4a2a07761a25 (diff)
downloadRoughlyEnoughItems-7b6c58c7db26747783aee7aff2eff87f08ecb8c3.tar.gz
RoughlyEnoughItems-7b6c58c7db26747783aee7aff2eff87f08ecb8c3.tar.bz2
RoughlyEnoughItems-7b6c58c7db26747783aee7aff2eff87f08ecb8c3.zip
Basic cheating / deleting
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java60
-rw-r--r--src/main/java/me/shedaniel/rei/client/ClientHelper.java124
-rw-r--r--src/main/java/me/shedaniel/rei/gui/ContainerGuiOverlay.java95
-rw-r--r--src/main/java/me/shedaniel/rei/gui/widget/HighlightableWidget.java13
-rw-r--r--src/main/java/me/shedaniel/rei/gui/widget/IWidget.java33
-rw-r--r--src/main/java/me/shedaniel/rei/gui/widget/ItemListOverlay.java126
-rw-r--r--src/main/java/me/shedaniel/rei/gui/widget/ItemSlotWidget.java101
-rw-r--r--src/main/java/me/shedaniel/rei/gui/widget/LabelWidget.java8
-rw-r--r--src/main/java/me/shedaniel/rei/gui/widget/QueuedTooltip.java18
-rw-r--r--src/main/java/me/shedaniel/rei/listeners/ClientLoaded.java7
-rw-r--r--src/main/java/me/shedaniel/rei/listeners/IMixinContainerGui.java (renamed from src/main/java/me/shedaniel/rei/mixin/IMixinContainerGui.java)10
-rw-r--r--src/main/java/me/shedaniel/rei/mixin/MixinContainerGui.java43
-rwxr-xr-xsrc/main/resources/assets/roughlyenoughitems/lang/en_us.json3
-rwxr-xr-xsrc/main/resources/fabric.mod.json5
14 files changed, 609 insertions, 37 deletions
diff --git a/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java b/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java
index 2db2dd69f..5431b3232 100644
--- a/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java
+++ b/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java
@@ -1,27 +1,48 @@
package me.shedaniel.rei;
+import me.shedaniel.rei.client.ClientHelper;
import me.shedaniel.rei.listeners.ClientTick;
import me.shedaniel.rei.listeners.IListener;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.events.client.ClientTickEvent;
+import net.fabricmc.fabric.networking.CustomPayloadPacketRegistry;
+import net.minecraft.item.ItemStack;
+import net.minecraft.server.network.ServerPlayNetworkHandler;
+import net.minecraft.server.network.ServerPlayerEntity;
+import net.minecraft.sortme.ChatMessageType;
+import net.minecraft.text.TranslatableTextComponent;
+import net.minecraft.util.Identifier;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
-public class RoughlyEnoughItemsCore implements ClientModInitializer {
+public class RoughlyEnoughItemsCore implements ClientModInitializer, ModInitializer {
- private static List<IListener> listeners = new ArrayList<>();
+ public static final Logger LOGGER = LogManager.getFormatterLogger("REI");
+ public static final Identifier DELETE_ITEMS_PACKET = new Identifier("roughlyenoughitems", "deleteitem");
+ public static final Identifier CREATE_ITEMS_PACKET = new Identifier("roughlyenoughitems", "createitem");
+ private static final List<IListener> listeners = new ArrayList<>();
+
+ public static <T> List<T> getListeners(Class<T> listenerClass) {
+ return listeners.stream().filter(listener -> {
+ return listenerClass.isAssignableFrom(listener.getClass());
+ }).map(listener -> {
+ return listenerClass.cast(listener);
+ }).collect(Collectors.toList());
+ }
@Override
public void onInitializeClient() {
- registerFabricEvents();
registerREIListeners();
+ registerFabricEvents();
}
private void registerREIListeners() {
-
+ registerListener(new ClientHelper());
}
private IListener registerListener(IListener listener) {
@@ -29,12 +50,11 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer {
return listener;
}
- public static <T> List<T> getListeners(Class<T> listenerClass) {
- return listeners.stream().filter(listener -> {
- return listenerClass.isAssignableFrom(listener.getClass());
- }).map(listener -> {
- return listenerClass.cast(listener);
- }).collect(Collectors.toList());
+ private boolean removeListener(IListener listener) {
+ if (!listeners.contains(listener))
+ return false;
+ listeners.remove(listener);
+ return true;
}
private void registerFabricEvents() {
@@ -43,4 +63,24 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer {
});
}
+ @Override
+ public void onInitialize() {
+ registerFabricPackets();
+ }
+
+ private void registerFabricPackets() {
+ CustomPayloadPacketRegistry.SERVER.register(DELETE_ITEMS_PACKET, (packetContext, packetByteBuf) -> {
+ ServerPlayerEntity player = (ServerPlayerEntity) packetContext.getPlayer();
+ if (!player.inventory.getCursorStack().isEmpty())
+ player.inventory.setCursorStack(ItemStack.EMPTY);
+ });
+ CustomPayloadPacketRegistry.SERVER.register(CREATE_ITEMS_PACKET, (packetContext, packetByteBuf) -> {
+ ServerPlayerEntity player = (ServerPlayerEntity) packetContext.getPlayer();
+ ItemStack stack = packetByteBuf.readItemStack();
+ if (player.inventory.insertStack(stack.copy()))
+ player.sendChatMessage(new TranslatableTextComponent("text.rei.cheat_items", stack.getDisplayName().getFormattedText(), stack.getAmount(), player.getEntityName()), ChatMessageType.SYSTEM);
+ else player.sendChatMessage(new TranslatableTextComponent("text.rei.failed_cheat_items"), ChatMessageType.SYSTEM);
+ });
+ }
+
}
diff --git a/src/main/java/me/shedaniel/rei/client/ClientHelper.java b/src/main/java/me/shedaniel/rei/client/ClientHelper.java
new file mode 100644
index 000000000..b0bc64a98
--- /dev/null
+++ b/src/main/java/me/shedaniel/rei/client/ClientHelper.java
@@ -0,0 +1,124 @@
+package me.shedaniel.rei.client;
+
+import com.google.common.collect.Lists;
+import io.netty.buffer.Unpooled;
+import me.shedaniel.rei.RoughlyEnoughItemsCore;
+import me.shedaniel.rei.listeners.ClientLoaded;
+import net.fabricmc.api.ClientModInitializer;
+import net.fabricmc.loader.FabricLoader;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.Mouse;
+import net.minecraft.enchantment.Enchantment;
+import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
+import net.minecraft.server.network.packet.CustomPayloadServerPacket;
+import net.minecraft.util.Identifier;
+import net.minecraft.util.PacketByteBuf;
+import net.minecraft.util.registry.Registry;
+
+import java.awt.*;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ClientHelper implements ClientLoaded, ClientModInitializer {
+
+ private static List<ItemStack> itemList;
+ private static boolean cheating;
+
+ public ClientHelper() {
+ this.itemList = Lists.newLinkedList();
+ }
+
+ public static String getModFromItemStack(ItemStack stack) {
+ if (!stack.isEmpty()) {
+ Identifier location = Registry.ITEM.getId(stack.getItem());
+ assert location != null;
+ String modid = location.getNamespace();
+ if (modid.equalsIgnoreCase("minecraft"))
+ return "Minecraft";
+ return FabricLoader.INSTANCE.getModContainers().stream()
+ .map(modContainer -> {
+ return modContainer.getInfo();
+ })
+ .filter(modInfo -> modInfo.getId().equals(modid) || (modInfo.getName() != null && modInfo.getName().equals(modid)))
+ .findFirst().map(modInfo -> {
+ if (modInfo.getName() != null)
+ return modInfo.getName();
+ return modid;
+ }).orElse(modid);
+ }
+ return "";
+ }
+
+ public static List<ItemStack> getItemList() {
+ return itemList;
+ }
+
+ public static Point getMouseLocation() {
+ MinecraftClient client = MinecraftClient.getInstance();
+ Mouse mouse = client.mouse;
+ double double_1 = mouse.getX() * (double) client.window.getScaledWidth() / (double) client.window.method_4480();
+ double double_2 = mouse.getY() * (double) client.window.getScaledHeight() / (double) client.window.method_4507();
+ return new Point((int) double_1, (int) double_2);
+ }
+
+ public static boolean isCheating() {
+ return cheating;
+ }
+
+ public static void sendDeletePacket() {
+ PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer());
+ MinecraftClient.getInstance().getNetworkHandler().sendPacket(new CustomPayloadServerPacket(RoughlyEnoughItemsCore.DELETE_ITEMS_PACKET, buf));
+ }
+
+ public static boolean tryCheatingStack(ItemStack cheatedStack) {
+ try {
+ PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer());
+ buf.writeItemStack(cheatedStack.copy());
+ MinecraftClient.getInstance().getNetworkHandler().sendPacket(new CustomPayloadServerPacket(RoughlyEnoughItemsCore.CREATE_ITEMS_PACKET, buf));
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ public static boolean executeRecipeKeyBind() {
+ return false;
+ }
+
+ public static boolean executeUsageKeyBind() {
+ return false;
+ }
+
+ @Override
+ public void clientLoaded() {
+ Registry.ITEM.forEach(this::registerItem);
+ Registry.ENCHANTMENT.forEach(enchantment -> {
+ for(int i = enchantment.getMinimumLevel(); i < enchantment.getMaximumLevel(); i++) {
+ Map<Enchantment, Integer> map = new HashMap<>();
+ map.put(enchantment, i);
+ ItemStack itemStack = new ItemStack(Items.ENCHANTED_BOOK);
+ EnchantmentHelper.set(map, itemStack);
+ registerItemStack(itemStack);
+ }
+ });
+ }
+
+ public void registerItem(Item item) {
+ registerItemStack(item.getDefaultStack());
+ }
+
+ public void registerItemStack(ItemStack stack) {
+ if (!stack.getItem().equals(Items.AIR))
+ itemList.add(stack);
+ }
+
+ @Override
+ public void onInitializeClient() {
+ this.cheating = true;
+ }
+
+}
diff --git a/src/main/java/me/shedaniel/rei/gui/ContainerGuiOverlay.java b/src/main/java/me/shedaniel/rei/gui/ContainerGuiOverlay.java
index 522566cc5..42bd77bf5 100644
--- a/src/main/java/me/shedaniel/rei/gui/ContainerGuiOverlay.java
+++ b/src/main/java/me/shedaniel/rei/gui/ContainerGuiOverlay.java
@@ -1,13 +1,18 @@
package me.shedaniel.rei.gui;
+import me.shedaniel.rei.RoughlyEnoughItemsCore;
+import me.shedaniel.rei.client.ClientHelper;
import me.shedaniel.rei.gui.widget.IWidget;
+import me.shedaniel.rei.gui.widget.ItemListOverlay;
import me.shedaniel.rei.gui.widget.LabelWidget;
-import me.shedaniel.rei.mixin.IMixinContainerGui;
+import me.shedaniel.rei.gui.widget.QueuedTooltip;
+import me.shedaniel.rei.listeners.IMixinContainerGui;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.ContainerGui;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.util.Window;
+import net.minecraft.util.math.MathHelper;
import java.awt.*;
import java.util.ArrayList;
@@ -18,41 +23,80 @@ public class ContainerGuiOverlay extends Gui {
private Rectangle rectangle;
private IMixinContainerGui containerGui;
private Window window;
- private int page;
- private List<IWidget> widgets;
+ private static int page = 0;
+ private final List<IWidget> widgets;
+ private ItemListOverlay itemListOverlay;
+ private ButtonWidget buttonLeft, buttonRight;
+ private final List<QueuedTooltip> queuedTooltips;
public ContainerGuiOverlay(ContainerGui containerGui) {
+ this.queuedTooltips = new ArrayList<>();
this.containerGui = (IMixinContainerGui) containerGui;
+ this.widgets = new ArrayList<>();
}
- @Override
- protected void onInitialized() {
+ public void onInitialized() {
//Update Variables
- this.widgets = new ArrayList<>();
+ this.widgets.clear();
this.window = MinecraftClient.getInstance().window;
if (MinecraftClient.getInstance().currentGui instanceof ContainerGui)
this.containerGui = (IMixinContainerGui) MinecraftClient.getInstance().currentGui;
- this.page = 0;
+ this.rectangle = calculateBoundary();
+ widgets.add(this.itemListOverlay = new ItemListOverlay(this, containerGui, page));
- rectangle = calculateBoundary();
- addButton(new ButtonWidget(-1, rectangle.x, rectangle.y + 3, 16, 20, "<") {
+ this.itemListOverlay.updateList(getItemListArea(), page);
+ addButton(buttonLeft = new ButtonWidget(-1, rectangle.x, rectangle.y + 3, 16, 20, "<") {
@Override
public void onPressed(double double_1, double double_2) {
- //Left Page
+ page--;
+ if (page < 0)
+ page = getTotalPage();
+ itemListOverlay.updateList(getItemListArea(), page);
}
});
- addButton(new ButtonWidget(-1, rectangle.x + rectangle.width - 18, rectangle.y + 3, 16, 20, ">") {
+ addButton(buttonRight = new ButtonWidget(-1, rectangle.x + rectangle.width - 18, rectangle.y + 3, 16, 20, ">") {
@Override
public void onPressed(double double_1, double double_2) {
- //Right Page
+ page++;
+ if (page > getTotalPage())
+ page = 0;
+ itemListOverlay.updateList(getItemListArea(), page);
+ }
+ });
+ this.widgets.add(new LabelWidget(rectangle.x + (rectangle.width / 2), rectangle.y + 10, "") {
+ @Override
+ public void draw(int mouseX, int mouseY, float partialTicks) {
+ this.text = String.format("%s/%s", page + 1, getTotalPage() + 1);
+ super.draw(mouseX, mouseY, partialTicks);
}
});
- widgets.add(new LabelWidget(rectangle.x + (rectangle.width / 2), rectangle.y + 10, String.format("%s/%s", page + 1, getTotalPage() + 1)));
+
+ this.listeners.addAll(widgets);
+ }
+
+ private Rectangle getItemListArea() {
+ return new Rectangle(rectangle.x + 2, rectangle.y + 24, rectangle.width - 4, rectangle.height - 27);
+ }
+
+ public Rectangle getRectangle() {
+ return rectangle;
+ }
+
+ public void render(int mouseX, int mouseY, float partialTicks) {
+ draw(mouseX, mouseY, partialTicks);
+ queuedTooltips.forEach(queuedTooltip -> containerGui.getContainerGui().drawTooltip(queuedTooltip.text, queuedTooltip.mouse.x, queuedTooltip.mouse.y));
+ queuedTooltips.clear();
+ }
+
+ public void addTooltip(QueuedTooltip queuedTooltip) {
+ queuedTooltips.add(queuedTooltip);
}
@Override
public void draw(int int_1, int int_2, float float_1) {
widgets.forEach(widget -> widget.draw(int_1, int_2, float_1));
+ itemListOverlay.draw(int_1, int_2, float_1);
+ super.draw(int_1, int_2, float_1);
}
private Rectangle calculateBoundary() {
@@ -62,7 +106,30 @@ public class ContainerGuiOverlay extends Gui {
}
private int getTotalPage() {
- return 10;
+ return MathHelper.ceil(ClientHelper.getItemList().size() / itemListOverlay.getTotalSlotsPerPage());
}
+ @Override
+ public boolean mouseScrolled(double amount) {
+ if (rectangle.contains(ClientHelper.getMouseLocation())) {
+ if (amount > 0 && buttonLeft.enabled)
+ buttonLeft.onPressed(0, 0);
+ else if (amount < 0 && buttonRight.enabled)
+ buttonRight.onPressed(0, 0);
+ else return false;
+ return true;
+ }
+ for(IWidget widget : widgets)
+ if (widget.mouseScrolled(amount))
+ return true;
+ return false;
+ }
+
+ @Override
+ public boolean mouseClicked(double double_1, double double_2, int int_1) {
+ for(IWidget widget : widgets)
+ if (widget.mouseClicked(double_1, double_2, int_1))
+ return true;
+ return false;
+ }
}
diff --git a/src/main/java/me/shedaniel/rei/gui/widget/HighlightableWidget.java b/src/main/java/me/shedaniel/rei/gui/widget/HighlightableWidget.java
new file mode 100644
index 000000000..97d097d94
--- /dev/null
+++ b/src/main/java/me/shedaniel/rei/gui/widget/HighlightableWidget.java
@@ -0,0 +1,13 @@
+package me.shedaniel.rei.gui.widget;
+
+import java.awt.*;
+
+public interface HighlightableWidget extends IWidget {
+
+ public Rectangle getBounds();
+
+ default boolean isHighlighted(int mouseX, int mouseY) {
+ return getBounds().contains(new Point(mouseX, mouseY));
+ }
+
+}
diff --git a/src/main/java/me/shedaniel/rei/gui/widget/IWidget.java b/src/main/java/me/shedaniel/rei/gui/widget/IWidget.java
index d63817563..2b0735d4a 100644
--- a/src/main/java/me/shedaniel/rei/gui/widget/IWidget.java
+++ b/src/main/java/me/shedaniel/rei/gui/widget/IWidget.java
@@ -1,9 +1,42 @@
package me.shedaniel.rei.gui.widget;
+import com.google.common.collect.Lists;
import net.minecraft.client.gui.GuiEventListener;
+import java.util.List;
+
public interface IWidget extends GuiEventListener {
+ public List<IWidget> getListeners();
+
public void draw(int mouseX, int mouseY, float partialTicks);
+ @Override
+ default boolean mouseClicked(double double_1, double double_2, int int_1) {
+ if (onMouseClick(int_1, double_1, double_2))
+ return true;
+ for(IWidget widget : getListeners())
+ if (widget.mouseClicked(double_1, double_2, int_1))
+ return true;
+ return false;
+ }
+
+ default boolean onMouseClick(int button, double mouseX, double mouseY) {
+ return false;
+ }
+
+ default boolean onMouseScrolled(double amount) {
+ return false;
+ }
+
+ @Override
+ default boolean mouseScrolled(double amount) {
+ if (onMouseScrolled(amount))
+ return true;
+ for(IWidget widget : getListeners())
+ if (widget.mouseScrolled(amount))
+ return true;
+ return false;
+ }
+
}
diff --git a/src/main/java/me/shedaniel/rei/gui/widget/ItemListOverlay.java b/src/main/java/me/shedaniel/rei/gui/widget/ItemListOverlay.java
new file mode 100644
index 000000000..98b5ef22d
--- /dev/null
+++ b/src/main/java/me/shedaniel/rei/gui/widget/ItemListOverlay.java
@@ -0,0 +1,126 @@
+package me.shedaniel.rei.gui.widget;
+
+import com.google.common.collect.Lists;
+import me.shedaniel.rei.RoughlyEnoughItemsCore;
+import me.shedaniel.rei.client.ClientHelper;
+import me.shedaniel.rei.gui.ContainerGuiOverlay;
+import me.shedaniel.rei.listeners.ClientLoaded;
+import me.shedaniel.rei.listeners.IMixinContainerGui;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.Drawable;
+import net.minecraft.client.network.ClientPlayerEntity;
+import net.minecraft.client.resource.language.I18n;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.math.MathHelper;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ItemListOverlay extends Drawable implements IWidget {
+
+ private ContainerGuiOverlay containerGuiOverlay;
+ private IMixinContainerGui containerGui;
+ private List<IWidget> widgets = new ArrayList<>();
+ private int width, height, page;
+ private Rectangle rectangle;
+
+ public ItemListOverlay(ContainerGuiOverlay containerGuiOverlay, IMixinContainerGui containerGui, int page) {
+ this.containerGuiOverlay = containerGuiOverlay;
+ this.containerGui = containerGui;
+ this.width = 0;
+ this.height = 0;
+ this.page = page;
+ }
+
+ public int getTotalSlotsPerPage() {
+ return width * height;
+ }
+
+ @Override
+ public void draw(int int_1, int int_2, float float_1) {
+ widgets.forEach(widget -> widget.draw(int_1, int_2, float_1));
+ }
+
+ public void updateList(int page) {
+ updateList(rectangle, page);
+ }
+
+ public void updateList(Rectangle rect, int page) {
+ this.rectangle = rect;
+ if (ClientHelper.getItemList().isEmpty())
+ RoughlyEnoughItemsCore.getListeners(ClientLoaded.class).forEach(ClientLoaded::clientLoaded);
+ List<ItemStack> stacks = ClientHelper.getItemList();
+ this.widgets.clear();
+ this.page = page;
+ calculateListSize(rect);
+ double startX = rect.getCenterX() - width * 9;
+ double startY = rect.getCenterY() - height * 9;
+ for(int i = 0; i < getTotalSlotsPerPage(); i++) {
+ int j = i + page * getTotalSlotsPerPage();
+ if (j >= stacks.size())
+ break;
+ widgets.add(new ItemSlotWidget((int) (startX + (i % width) * 18), (int) (startY + MathHelper.floor(i / width) * 18),
+ stacks.get(j), false, true, containerGui) {
+ @Override
+ protected List<String> getTooltip(ItemStack itemStack) {
+ if (!ClientHelper.isCheating() || MinecraftClient.getInstance().player.inventory.getCursorStack().isEmpty())
+ return super.getTooltip(itemStack);
+ List<String> list = Lists.newArrayList();
+ list.add(I18n.translate("text.rei.delete_items"));
+ return list;
+ }
+
+ @Override
+ public boolean onMouseClick(int button, double mouseX, double mouseY) {
+ ClientPlayerEntity player = MinecraftClient.getInstance().player;
+ if (getBounds().contains(mouseX, mouseY)) {
+ if (ClientHelper.isCheating() && !player.inventory.getCursorStack().isEmpty()) {
+ ClientHelper.sendDeletePacket();
+ return true;
+ }
+ if (!player.inventory.getCursorStack().isEmpty())
+ return false;
+ if (ClientHelper.isCheating()) {
+ if (getCurrentStack() != null && !getCurrentStack().isEmpty()) {
+ ItemStack cheatedStack = getCurrentStack().copy();
+ cheatedStack.setAmount(button == 0 ? 1 : button == 1 ? cheatedStack.getMaxAmount() : cheatedStack.getAmount());
+ return ClientHelper.tryCheatingStack(cheatedStack);
+ }
+ } else {
+ if (button == 0)
+ return ClientHelper.executeRecipeKeyBind();
+ else if (button == 1)
+ return ClientHelper.executeUsageKeyBind();
+ }
+ }
+ return false;
+ }
+ });
+ }
+ }
+
+ private void calculateListSize(Rectangle rect) {
+ int xOffset = 0, yOffset = 0;
+ this.width = 0;
+ this.height = 0;
+ while (true) {
+ xOffset += 18;
+ if (height == 0)
+ width++;
+ if (xOffset + 19 > rect.width) {
+ xOffset = 0;
+ yOffset += 18;
+ height++;
+ }
+ if (yOffset + 19 > rect.height)
+ break;
+ }
+ }
+
+ @Override
+ public List<IWidget> getListeners() {
+ return widgets;
+ }
+
+}
diff --git a/src/main/java/me/shedaniel/rei/gui/widget/ItemSlotWidget.java b/src/main/java/me/shedaniel/rei/gui/widget/ItemSlotWidget.java
new file mode 100644
index 000000000..292f5e5f5
--- /dev/null
+++ b/src/main/java/me/shedaniel/rei/gui/widget/ItemSlotWidget.java
@@ -0,0 +1,101 @@
+package me.shedaniel.rei.gui.widget;
+
+import com.google.common.collect.Lists;
+import me.shedaniel.rei.client.ClientHelper;
+import me.shedaniel.rei.listeners.IMixinContainerGui;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.ContainerGui;
+import net.minecraft.client.gui.Drawable;
+import net.minecraft.client.render.GuiLighting;
+import net.minecraft.client.render.item.ItemRenderer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.Identifier;
+import net.minecraft.util.math.MathHelper;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class ItemSlotWidget extends Drawable implements HighlightableWidget {
+
+ private static final Identifier RECIPE_GUI = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer.png");
+ private List<ItemStack> itemList = new LinkedList<>();
+ private boolean drawBackground, showToolTips;
+ private int x, y;
+ private IMixinContainerGui containerGui;
+
+ public ItemSlotWidget(int x, int y, ItemStack itemStack, boolean drawBackground, boolean showToolTips, IMixinContainerGui containerGui) {
+ this(x, y, Arrays.asList(itemStack), drawBackground, showToolTips, containerGui);
+ }
+
+ public ItemSlotWidget(int x, int y, List<ItemStack> itemList, boolean drawBackground, boolean showToolTips, IMixinContainerGui containerGui) {
+ this.itemList = itemList;
+ this.drawBackground = drawBackground;
+ this.showToolTips = showToolTips;
+ this.x = x;
+ this.y = y;
+ this.containerGui = containerGui;
+ }
+
+ public boolean isDrawBackground() {
+ return drawBackground;
+ }
+
+ @Override
+ public List<IWidget> getListeners() {
+ return new ArrayList<>();
+ }
+
+ @Override
+ public void draw(int mouseX, int mouseY, float partialTicks) {
+ final ItemStack itemStack = getCurrentStack();
+ if (drawBackground) {
+ MinecraftClient.getInstance().getTextureManager().bindTexture(RECIPE_GUI);
+ drawTexturedRect(this.x - 1, this.y - 1, 0, 222, 18, 18);
+ }
+ if (itemStack.isEmpty())
+ return;
+ GuiLighting.enableForItems();
+ ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer();
+ itemRenderer.zOffset = 200.0F;
+ itemRenderer.renderItemAndGlowInGui(itemStack, x, y);
+ assert containerGui != null;
+ if (containerGui.getDraggedStack().isEmpty())
+ itemRenderer.renderItemOverlaysInGUIWithText(MinecraftClient.getInstance().fontRenderer, itemStack, x, y - 0, getItemCountOverlay(itemStack));
+ else
+ itemRenderer.renderItemOverlaysInGUIWithText(MinecraftClient.getInstance().fontRenderer, itemStack, x, y - 8, getItemCountOverlay(itemStack));
+ itemRenderer.zOffset = 0.0F;
+ if (isHighlighted(mouseX, mouseY) && showToolTips) {
+ List<String> toolTip = getTooltip(itemStack);
+ containerGui.getOverlay().addTooltip(new QueuedTooltip(new Point(mouseX, mouseY), toolTip));
+ }
+ }
+
+ protected List<String> getTooltip(ItemStack itemStack) {
+ final String modString = "§9§o" + ClientHelper.getModFromItemStack(itemStack);
+ MinecraftClient mc = MinecraftClient.getInstance();
+ List<String> toolTip = Lists.newArrayList();
+ if (containerGui != null)
+ toolTip = containerGui.getContainerGui().getStackTooltip(itemStack).stream().filter(s -> !s.equals(modString)).collect(Collectors.toList());
+ else toolTip.add(itemStack.getDisplayName().getFormattedText());
+ toolTip.add("§9§o" + ClientHelper.getModFromItemStack(itemStack));
+ return toolTip;
+ }
+
+ protected String getItemCountOverlay(ItemStack currentStack) {
+ return "";
+ }
+
+ protected ItemStack getCurrentStack() {
+ return itemList.get(MathHelper.clamp((int) (System.currentTimeMillis() / 500) % itemList.size(), 0, itemList.size() - 1));
+ }
+
+ @Override
+ public Rectangle getBounds() {
+ return new Rectangle(this.x, this.y, 18, 18);
+ }
+
+}
diff --git a/src/main/java/me/shedaniel/rei/gui/widget/LabelWidget.java b/src/main/java/me/shedaniel/rei/gui/widget/LabelWidget.java
index a93760dc8..e959c5623 100644
--- a/src/main/java/me/shedaniel/rei/gui/widget/LabelWidget.java
+++ b/src/main/java/me/shedaniel/rei/gui/widget/LabelWidget.java
@@ -4,6 +4,9 @@ import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Drawable;
import net.minecraft.client.gui.GuiEventListener;
+import java.util.ArrayList;
+import java.util.List;
+
public class LabelWidget extends Drawable implements IWidget {
public int x;
@@ -17,6 +20,11 @@ public class LabelWidget extends Drawable implements IWidget {
}
@Override
+ public List<IWidget> getListeners() {
+ return new ArrayList<>();
+ }
+
+ @Override
public void draw(int mouseX, int mouseY, float partialTicks) {
drawStringCentered(MinecraftClient.getInstance().fontRenderer, text, x, y, -1);
}
diff --git a/src/main/java/me/shedaniel/rei/gui/widget/QueuedTooltip.java b/src/main/java/me/shedaniel/rei/gui/widget/QueuedTooltip.java
new file mode 100644
index 000000000..8d6d82796
--- /dev/null
+++ b/src/main/java/me/shedaniel/rei/gui/widget/QueuedTooltip.java
@@ -0,0 +1,18 @@
+package me.shedaniel.rei.gui.widget;
+
+
+import java.awt.*;
+import java.util.LinkedList;
+import java.util.List;
+
+public class QueuedTooltip {
+
+ public Point mouse;
+ public List<String> text;
+
+ public QueuedTooltip(Point mouse, List<String> text) {
+ this.mouse = mouse;
+ this.text = new LinkedList<>(text);
+ }
+
+}
diff --git a/src/main/java/me/shedaniel/rei/listeners/ClientLoaded.java b/src/main/java/me/shedaniel/rei/listeners/ClientLoaded.java
new file mode 100644
index 000000000..0d370d620
--- /dev/null
+++ b/src/main/java/me/shedaniel/rei/listeners/ClientLoaded.java
@@ -0,0 +1,7 @@
+package me.shedaniel.rei.listeners;
+
+public interface ClientLoaded extends IListener {
+
+ public void clientLoaded();
+
+}
diff --git a/src/main/java/me/shedaniel/rei/mixin/IMixinContainerGui.java b/src/main/java/me/shedaniel/rei/listeners/IMixinContainerGui.java
index 2725e0b7d..612d4c304 100644
--- a/src/main/java/me/shedaniel/rei/mixin/IMixinContainerGui.java
+++ b/src/main/java/me/shedaniel/rei/listeners/IMixinContainerGui.java
@@ -1,6 +1,10 @@
-package me.shedaniel.rei.mixin;
+package me.shedaniel.rei.listeners;
import me.shedaniel.rei.gui.ContainerGuiOverlay;
+import net.minecraft.client.gui.ContainerGui;
+import net.minecraft.item.ItemStack;
+
+import java.util.List;
public interface IMixinContainerGui {
@@ -12,6 +16,10 @@ public interface IMixinContainerGui {
public int getContainerHeight();
+ public ItemStack getDraggedStack();
+
public ContainerGuiOverlay getOverlay();
+ public ContainerGui getContainerGui();
+
}
diff --git a/src/main/java/me/shedaniel/rei/mixin/MixinContainerGui.java b/src/main/java/me/shedaniel/rei/mixin/MixinContainerGui.java
index 00aa124b7..8e809b93f 100644
--- a/