aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/me/shedaniel/rei/impl
diff options
context:
space:
mode:
authorDanielshe <shekwancheung0528@gmail.com>2019-11-03 14:44:52 +0800
committerDanielshe <shekwancheung0528@gmail.com>2019-11-03 14:44:59 +0800
commit9f5a9eae9a7863412cc5eb433bf15e5ee71da616 (patch)
tree0e6b0b94af061c5e9023b1ff19f339a6c30149be /src/main/java/me/shedaniel/rei/impl
parent3e3e25855b9f6df507a7d4c8a07c64b9a502fae2 (diff)
downloadRoughlyEnoughItems-9f5a9eae9a7863412cc5eb433bf15e5ee71da616.tar.gz
RoughlyEnoughItems-9f5a9eae9a7863412cc5eb433bf15e5ee71da616.tar.bz2
RoughlyEnoughItems-9f5a9eae9a7863412cc5eb433bf15e5ee71da616.zip
3.2.1
Diffstat (limited to 'src/main/java/me/shedaniel/rei/impl')
-rw-r--r--src/main/java/me/shedaniel/rei/impl/AbstractEntryStack.java78
-rw-r--r--src/main/java/me/shedaniel/rei/impl/BaseBoundsHandlerImpl.java30
-rw-r--r--src/main/java/me/shedaniel/rei/impl/ClientHelperImpl.java20
-rw-r--r--src/main/java/me/shedaniel/rei/impl/DisplayHelperImpl.java22
-rw-r--r--src/main/java/me/shedaniel/rei/impl/EmptyEntryStack.java96
-rw-r--r--src/main/java/me/shedaniel/rei/impl/EntryRegistryImpl.java30
-rw-r--r--src/main/java/me/shedaniel/rei/impl/FluidEntry.java15
-rw-r--r--src/main/java/me/shedaniel/rei/impl/FluidEntryStack.java186
-rw-r--r--src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java158
-rw-r--r--src/main/java/me/shedaniel/rei/impl/ItemStackEntry.java15
-rw-r--r--src/main/java/me/shedaniel/rei/impl/ObjectHolderImpl.java51
-rw-r--r--src/main/java/me/shedaniel/rei/impl/RecipeHelperImpl.java49
-rw-r--r--src/main/java/me/shedaniel/rei/impl/ScreenHelper.java17
13 files changed, 685 insertions, 82 deletions
diff --git a/src/main/java/me/shedaniel/rei/impl/AbstractEntryStack.java b/src/main/java/me/shedaniel/rei/impl/AbstractEntryStack.java
new file mode 100644
index 000000000..e32ac3275
--- /dev/null
+++ b/src/main/java/me/shedaniel/rei/impl/AbstractEntryStack.java
@@ -0,0 +1,78 @@
+/*
+ * Roughly Enough Items by Danielshe.
+ * Licensed under the MIT License.
+ */
+
+package me.shedaniel.rei.impl;
+
+import me.shedaniel.rei.api.EntryStack;
+import me.shedaniel.rei.api.ObjectHolder;
+import net.minecraft.client.gui.DrawableHelper;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Deprecated
+public abstract class AbstractEntryStack extends DrawableHelper implements EntryStack {
+ private Map<Settings, Object> settings = new HashMap<>();
+
+ @Override
+ public <T> EntryStack setting(Settings<T> settings, T value) {
+ this.settings.put(settings, value);
+ return this;
+ }
+
+ @Override
+ public <T> EntryStack removeSetting(Settings<T> settings) {
+ this.settings.remove(settings);
+ return this;
+ }
+
+ @Override
+ public EntryStack clearSettings() {
+ this.settings.clear();
+ return this;
+ }
+
+ protected Map<Settings, Object> getSettings() {
+ return settings;
+ }
+
+ @Override
+ public <T> ObjectHolder<T> getSetting(Settings<T> settings) {
+ Object o = this.settings.get(settings);
+ if (o == null)
+ return new ObjectHolderImpl(settings.getDefaultValue());
+ return new ObjectHolderImpl(o);
+ }
+
+ @Override
+ public boolean equals(EntryStack stack, boolean ignoreTags, boolean ignoreAmount) {
+ if (ignoreTags && ignoreAmount)
+ return equalsIgnoreTagsAndAmount(stack);
+ if (ignoreAmount)
+ return equalsIgnoreAmount(stack);
+ if (ignoreTags)
+ return equalsIgnoreTags(stack);
+ return equalsAll(stack);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof EntryStack))
+ return false;
+ EntryStack stack = (EntryStack) obj;
+ boolean checkTags = getSetting(Settings.CHECK_TAGS).value().get() || stack.getSetting(Settings.CHECK_TAGS).value().get();
+ return equals(stack, !checkTags, true);
+ }
+
+ @Override
+ public int getZ() {
+ return blitOffset;
+ }
+
+ @Override
+ public void setZ(int z) {
+ blitOffset = z;
+ }
+}
diff --git a/src/main/java/me/shedaniel/rei/impl/BaseBoundsHandlerImpl.java b/src/main/java/me/shedaniel/rei/impl/BaseBoundsHandlerImpl.java
index cd7b955ad..f8af275de 100644
--- a/src/main/java/me/shedaniel/rei/impl/BaseBoundsHandlerImpl.java
+++ b/src/main/java/me/shedaniel/rei/impl/BaseBoundsHandlerImpl.java
@@ -21,14 +21,7 @@ import java.util.function.Function;
public class BaseBoundsHandlerImpl implements BaseBoundsHandler {
- private static final Function<Rectangle, Long> RECTANGLE_LONG_FUNCTION = r -> r.x + 1000l * r.y + 1000000l * r.width + 1000000000l * r.height;
- private static final Comparator<Pair<Pair<Class<?>, Float>, Function<Boolean, List<Rectangle>>>> LIST_PAIR_COMPARATOR;
- private static final Comparator<? super Rectangle> RECTANGLE_COMPARER = Comparator.comparingLong(RECTANGLE_LONG_FUNCTION::apply);
-
- static {
- Comparator<Pair<Pair<Class<?>, Float>, Function<Boolean, List<Rectangle>>>> comparator = Comparator.comparingDouble(value -> value.getLeft().getRight());
- LIST_PAIR_COMPARATOR = comparator.reversed();
- }
+ private static final Comparator<? super Rectangle> RECTANGLE_COMPARER = Comparator.comparingLong(Rectangle::hashCode);
private long lastArea = -1;
private List<Pair<Pair<Class<?>, Float>, Function<Boolean, List<Rectangle>>>> list = Lists.newArrayList();
@@ -63,19 +56,16 @@ public class BaseBoundsHandlerImpl implements BaseBoundsHandler {
@Override
public boolean shouldRecalculateArea(boolean isOnRightSide, Rectangle rectangle) {
- long current = getStringFromCurrent(isOnRightSide);
+ long current = currentHashCode(isOnRightSide);
if (lastArea == current)
return false;
lastArea = current;
return true;
}
- private DisplayHelper.DisplayBoundsHandler getHandler() {
- return RoughlyEnoughItemsCore.getDisplayHelper().getResponsibleBoundsHandler(MinecraftClient.getInstance().currentScreen.getClass());
- }
-
- private long getStringFromCurrent(boolean isOnRightSide) {
- return getLongFromAreas(isOnRightSide ? getHandler().getRightBounds(MinecraftClient.getInstance().currentScreen) : getHandler().getLeftBounds(MinecraftClient.getInstance().currentScreen), getCurrentExclusionZones(MinecraftClient.getInstance().currentScreen.getClass(), isOnRightSide, false));
+ private long currentHashCode(boolean isOnRightSide) {
+ DisplayHelper.DisplayBoundsHandler handler = RoughlyEnoughItemsCore.getDisplayHelper().getResponsibleBoundsHandler(MinecraftClient.getInstance().currentScreen.getClass());
+ return areasHashCode(isOnRightSide ? handler.getRightBounds(MinecraftClient.getInstance().currentScreen) : handler.getLeftBounds(MinecraftClient.getInstance().currentScreen), getCurrentExclusionZones(MinecraftClient.getInstance().currentScreen.getClass(), isOnRightSide, false));
}
@Override
@@ -103,11 +93,11 @@ public class BaseBoundsHandlerImpl implements BaseBoundsHandler {
list.add(new Pair<>(new Pair<>(screenClass, 0f), supplier));
}
- public long getLongFromAreas(Rectangle rectangle, List<Rectangle> exclusionZones) {
- long a = RECTANGLE_LONG_FUNCTION.apply(rectangle);
- for (Rectangle exclusionZone : exclusionZones)
- a -= RECTANGLE_LONG_FUNCTION.apply(exclusionZone);
- return a;
+ private long areasHashCode(Rectangle rectangle, List<Rectangle> exclusionZones) {
+ int hashCode = 31 + (rectangle == null ? 0 : rectangle.hashCode());
+ for (Rectangle e : exclusionZones)
+ hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
+ return hashCode;
}
}
diff --git a/src/main/java/me/shedaniel/rei/impl/ClientHelperImpl.java b/src/main/java/me/shedaniel/rei/impl/ClientHelperImpl.java
index 748869a3c..0115104fb 100644
--- a/src/main/java/me/shedaniel/rei/impl/ClientHelperImpl.java
+++ b/src/main/java/me/shedaniel/rei/impl/ClientHelperImpl.java
@@ -10,10 +10,7 @@ import com.google.common.collect.Maps;
import io.netty.buffer.Unpooled;
import me.shedaniel.rei.RoughlyEnoughItemsCore;
import me.shedaniel.rei.RoughlyEnoughItemsNetwork;
-import me.shedaniel.rei.api.ClientHelper;
-import me.shedaniel.rei.api.RecipeCategory;
-import me.shedaniel.rei.api.RecipeDisplay;
-import me.shedaniel.rei.api.RecipeHelper;
+import me.shedaniel.rei.api.*;
import me.shedaniel.rei.gui.PreRecipeViewingScreen;
import me.shedaniel.rei.gui.RecipeViewingScreen;
import me.shedaniel.rei.gui.VillagerRecipeViewingScreen;
@@ -155,16 +152,21 @@ public class ClientHelperImpl implements ClientHelper, ClientModInitializer {
}
@Override
- public boolean tryCheatingStack(ItemStack cheatedStack) {
+ public boolean tryCheatingEntry(EntryStack entry) {
+ if (entry.getType() != EntryStack.Type.ITEM)
+ return false;
+ ItemStack cheatedStack = entry.getItemStack().copy();
if (RoughlyEnoughItemsCore.canUsePackets()) {
try {
- ClientSidePacketRegistry.INSTANCE.sendToServer(RoughlyEnoughItemsNetwork.CREATE_ITEMS_PACKET, new PacketByteBuf(Unpooled.buffer()).writeItemStack(cheatedStack.copy()));
+ ClientSidePacketRegistry.INSTANCE.sendToServer(RoughlyEnoughItemsNetwork.CREATE_ITEMS_PACKET, new PacketByteBuf(Unpooled.buffer()).writeItemStack(cheatedStack));
return true;
} catch (Exception e) {
return false;
}
} else {
- Identifier identifier = Registry.ITEM.getId(cheatedStack.getItem());
+ Identifier identifier = entry.getIdentifier().orElse(null);
+ if (identifier == null)
+ return false;
String tagMessage = cheatedStack.copy().getTag() != null && !cheatedStack.copy().getTag().isEmpty() ? cheatedStack.copy().getTag().asString() : "";
String og = cheatedStack.getCount() == 1 ? RoughlyEnoughItemsCore.getConfigManager().getConfig().getGiveCommand().replaceAll(" \\{count}", "") : RoughlyEnoughItemsCore.getConfigManager().getConfig().getGiveCommand();
String madeUpCommand = og.replaceAll("\\{player_name}", MinecraftClient.getInstance().player.getEntityName()).replaceAll("\\{item_name}", identifier.getPath()).replaceAll("\\{item_identifier}", identifier.toString()).replaceAll("\\{nbt}", tagMessage).replaceAll("\\{count}", String.valueOf(cheatedStack.getCount()));
@@ -178,7 +180,7 @@ public class ClientHelperImpl implements ClientHelper, ClientModInitializer {
}
@Override
- public boolean executeRecipeKeyBind(ItemStack stack) {
+ public boolean executeRecipeKeyBind(EntryStack stack) {
Map<RecipeCategory<?>, List<RecipeDisplay>> map = RecipeHelper.getInstance().getRecipesFor(stack);
if (map.keySet().size() > 0)
openRecipeViewingScreen(map);
@@ -186,7 +188,7 @@ public class ClientHelperImpl implements ClientHelper, ClientModInitializer {
}
@Override
- public boolean executeUsageKeyBind(ItemStack stack) {
+ public boolean executeUsageKeyBind(EntryStack stack) {
Map<RecipeCategory<?>, List<RecipeDisplay>> map = RecipeHelper.getInstance().getUsagesFor(stack);
if (map.keySet().size() > 0)
openRecipeViewingScreen(map);
diff --git a/src/main/java/me/shedaniel/rei/impl/DisplayHelperImpl.java b/src/main/java/me/shedaniel/rei/impl/DisplayHelperImpl.java
index cf182ebf5..2abf3ddd8 100644
--- a/src/main/java/me/shedaniel/rei/impl/DisplayHelperImpl.java
+++ b/src/main/java/me/shedaniel/rei/impl/DisplayHelperImpl.java
@@ -50,12 +50,13 @@ public class DisplayHelperImpl implements DisplayHelper {
private Map<Class<?>, DisplayBoundsHandler<?>> handlerCache = Maps.newHashMap();
private Map<Class, List<DisplayBoundsHandler<?>>> handlerSortedCache = Maps.newHashMap();
private BaseBoundsHandler baseBoundsHandler;
- private Class tempScreen;
+ private Class<?> tempScreen;
@Override
public List<DisplayBoundsHandler<?>> getSortedBoundsHandlers(Class<?> screenClass) {
- if (handlerSortedCache.containsKey(screenClass))
- return handlerSortedCache.get(screenClass);
+ List<DisplayBoundsHandler<?>> possibleCached = handlerSortedCache.get(screenClass);
+ if (possibleCached != null)
+ return possibleCached;
tempScreen = screenClass;
handlerSortedCache.put(screenClass, screenDisplayBoundsHandlers.stream().filter(this::filterResponsible).sorted(BOUNDS_HANDLER_COMPARATOR).collect(Collectors.toList()));
return handlerSortedCache.get(screenClass);
@@ -68,14 +69,16 @@ public class DisplayHelperImpl implements DisplayHelper {
@Override
public DisplayBoundsHandler<?> getResponsibleBoundsHandler(Class<?> screenClass) {
- if (handlerCache.containsKey(screenClass))
- return handlerCache.get(screenClass);
- tempScreen = screenClass;
- handlerCache.put(screenClass, screenDisplayBoundsHandlers.stream().filter(this::filterResponsible).sorted(BOUNDS_HANDLER_COMPARATOR).findAny().orElse(EMPTY));
+ DisplayBoundsHandler<?> possibleCached = handlerCache.get(screenClass);
+ if (possibleCached != null)
+ return possibleCached;
+ List<DisplayBoundsHandler<?>> handlers = getSortedBoundsHandlers(screenClass);
+ handlerCache.put(screenClass, handlers.isEmpty() ? EMPTY : handlers.get(0));
return handlerCache.get(screenClass);
}
- public boolean filterResponsible(DisplayBoundsHandler handler) {
+ @Deprecated
+ public boolean filterResponsible(DisplayBoundsHandler<?> handler) {
return handler.getBaseSupportedClass().isAssignableFrom(tempScreen);
}
@@ -89,14 +92,17 @@ public class DisplayHelperImpl implements DisplayHelper {
return baseBoundsHandler;
}
+ @Deprecated
public void setBaseBoundsHandler(BaseBoundsHandler baseBoundsHandler) {
this.baseBoundsHandler = baseBoundsHandler;
}
+ @Deprecated
public void resetData() {
screenDisplayBoundsHandlers.clear();
}
+ @Deprecated
public void resetCache() {
handlerCache.clear();
handlerSortedCache.clear();
diff --git a/src/main/java/me/shedaniel/rei/impl/EmptyEntryStack.java b/src/main/java/me/shedaniel/rei/impl/EmptyEntryStack.java
new file mode 100644
index 000000000..a4cae7fa2
--- /dev/null
+++ b/src/main/java/me/shedaniel/rei/impl/EmptyEntryStack.java
@@ -0,0 +1,96 @@
+/*
+ * Roughly Enough Items by Danielshe.
+ * Licensed under the MIT License.
+ */
+
+package me.shedaniel.rei.impl;
+
+import me.shedaniel.math.api.Rectangle;
+import me.shedaniel.rei.api.Entry;
+import me.shedaniel.rei.api.EntryStack;
+import me.shedaniel.rei.gui.widget.QueuedTooltip;
+import net.minecraft.util.Identifier;
+
+import javax.annotation.Nullable;
+import java.util.Optional;
+
+@Deprecated
+public class EmptyEntryStack extends AbstractEntryStack {
+
+ @Deprecated
+ public static final EntryStack EMPTY = new EmptyEntryStack();
+
+ private EmptyEntryStack() {
+ }
+
+ @Override
+ public Optional<Identifier> getIdentifier() {
+ return Optional.empty();
+ }
+
+ @Override
+ public Type getType() {
+ return Type.EMPTY;
+ }
+
+ @Override
+ public int getAmount() {
+ return 0;
+ }
+
+ @Override
+ public void setAmount(int amount) {
+
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return true;
+ }
+
+ @Override
+ public Entry toEntry() {
+ return null;
+ }
+
+ @Override
+ public EntryStack copy() {
+ return this;
+ }
+
+ @Override
+ public Object getObject() {
+ return null;
+ }
+
+ @Override
+ public boolean equalsIgnoreTagsAndAmount(EntryStack stack) {
+ return stack.getType() == getType();
+ }
+
+ @Override
+ public boolean equalsIgnoreTags(EntryStack stack) {
+ return stack.getType() == getType();
+ }
+
+ @Override
+ public boolean equalsIgnoreAmount(EntryStack stack) {
+ return stack.getType() == getType();
+ }
+
+ @Override
+ public boolean equalsAll(EntryStack stack) {
+ return stack.getType() == getType();
+ }
+
+ @Override
+ @Nullable
+ public QueuedTooltip getTooltip(int mouseX, int mouseY) {
+ return null;
+ }
+
+ @Override
+ public void render(Rectangle bounds, int mouseX, int mouseY, float delta) {
+
+ }
+}
diff --git a/src/main/java/me/shedaniel/rei/impl/EntryRegistryImpl.java b/src/main/java/me/shedaniel/rei/impl/EntryRegistryImpl.java
index 9819b09c1..541cd97b9 100644
--- a/src/main/java/me/shedaniel/rei/impl/EntryRegistryImpl.java
+++ b/src/main/java/me/shedaniel/rei/impl/EntryRegistryImpl.java
@@ -6,15 +6,12 @@
package me.shedaniel.rei.impl;
import com.google.common.collect.Lists;
-import me.shedaniel.rei.api.Entry;
import me.shedaniel.rei.api.EntryRegistry;
-import net.minecraft.fluid.Fluid;
+import me.shedaniel.rei.api.EntryStack;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
-import net.minecraft.item.Items;
import net.minecraft.util.DefaultedList;
-import java.util.Collections;
import java.util.List;
import java.util.TreeSet;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -22,16 +19,10 @@ import java.util.stream.Collectors;
public class EntryRegistryImpl implements EntryRegistry {
- private final CopyOnWriteArrayList<Entry> entries = Lists.newCopyOnWriteArrayList();
+ private final CopyOnWriteArrayList<EntryStack> entries = Lists.newCopyOnWriteArrayList();
@Override
- public List<Entry> getEntryList() {
- return Collections.unmodifiableList(entries);
- }
-
- @SuppressWarnings("deprecation")
- @Override
- public List<Entry> getModifiableEntryList() {
+ public List<EntryStack> getStacksList() {
return entries;
}
@@ -45,22 +36,17 @@ public class EntryRegistryImpl implements EntryRegistry {
}
@Override
- public void registerItemStack(Item afterItem, ItemStack stack) {
+ public void registerEntryAfter(EntryStack afterEntry, EntryStack stack) {
if (!stack.isEmpty() && !alreadyContain(stack))
- if (afterItem == null || afterItem.equals(Items.AIR))
- entries.add(Entry.create(stack));
+ if (afterEntry == null || afterEntry.isEmpty())
+ entries.add(stack);
else {
int last = entries.size();
for (int i = 0; i < entries.size(); i++)
- if (entries.get(i).getEntryType() == Entry.Type.ITEM && entries.get(i).getItemStack().getItem().equals(afterItem))
+ if (entries.get(i).equalsAll(afterEntry))
last = i + 1;
- entries.add(last, Entry.create(stack));
+ entries.add(last, stack);
}
}
- @Override
- public void registerFluid(Fluid fluid) {
- entries.add(Entry.create(fluid));
- }
-
}
diff --git a/src/main/java/me/shedaniel/rei/impl/FluidEntry.java b/src/main/java/me/shedaniel/rei/impl/FluidEntry.java
index d89002df2..795ed0deb 100644
--- a/src/main/java/me/shedaniel/rei/impl/FluidEntry.java
+++ b/src/main/java/me/shedaniel/rei/impl/FluidEntry.java
@@ -6,11 +6,14 @@
package me.shedaniel.rei.impl;
import me.shedaniel.rei.api.Entry;
+import me.shedaniel.rei.api.annotations.ToBeRemoved;
import net.minecraft.fluid.Fluid;
import net.minecraft.item.ItemStack;
import javax.annotation.Nullable;
+@ToBeRemoved
+@Deprecated
public class FluidEntry implements Entry {
private Fluid fluid;
@@ -35,4 +38,16 @@ public class FluidEntry implements Entry {
public Fluid getFluid() {
return fluid;
}
+
+ @Override
+ public Entry clone() {
+ return this;
+ }
+
+ @Override
+ public boolean equalsEntry(Entry other, boolean checkTags) {
+ if (other.getEntryType() == Type.FLUID) {
+ return other.getFluid().matchesType(getFluid());
+ } else return false;
+ }
}
diff --git a/src/main/java/me/shedaniel/rei/impl/FluidEntryStack.java b/src/main/java/me/shedaniel/rei/impl/FluidEntryStack.java
new file mode 100644
index 000000000..c76c53c22
--- /dev/null
+++ b/src/main/java/me/shedaniel/rei/impl/FluidEntryStack.java
@@ -0,0 +1,186 @@
+/*
+ * Roughly Enough Items by Danielshe.
+ * Licensed under the MIT License.
+ */
+
+package me.shedaniel.rei.impl;
+
+import com.google.common.collect.Lists;
+import me.shedaniel.math.api.Rectangle;
+import me.shedaniel.rei.RoughlyEnoughItemsCore;
+import me.shedaniel.rei.api.ClientHelper;
+import me.shedaniel.rei.api.Entry;
+import me.shedaniel.rei.api.EntryStack;
+import me.shedaniel.rei.gui.widget.EntryListWidget;
+import me.shedaniel.rei.gui.widget.QueuedTooltip;
+import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler;
+import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.render.BufferBuilder;
+import net.minecraft.client.render.GuiLighting;
+import net.minecraft.client.render.Tessellator;
+import net.minecraft.client.render.VertexFormats;
+import net.minecraft.client.texture.Sprite;
+import net.minecraft.client.texture.SpriteAtlasTexture;
+import net.minecraft.fluid.Fluid;
+import net.minecraft.fluid.Fluids;
+import net.minecraft.util.Identifier;
+import net.minecraft.util.Pair;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.registry.Registry;
+
+import javax.annotation.Nullable;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+@Deprecated
+public class FluidEntryStack extends AbstractEntryStack {
+ private static final Map<Fluid, Pair<Sprite, Integer>> FLUID_SPRITE_CACHE = new HashMap<>();
+ private Fluid fluid;
+ private int amount;
+
+ public FluidEntryStack(Fluid fluid, int amount) {
+ this.fluid = fluid;
+ this.amount = amount;
+ }
+
+ protected static Pair<Sprite, Integer> getOrLoadSprite(Fluid fluid) {
+ Pair<Sprite, Integer> possibleCached = FLUID_SPRITE_CACHE.get(fluid);
+ if (possibleCached != null)
+ return possibleCached;
+
+ FluidRenderHandler fluidRenderHandler = FluidRenderHandlerRegistry.INSTANCE.get(fluid);
+ if (fluidRenderHandler == null)
+ return null;
+ Sprite[] sprites = fluidRenderHandler.getFluidSprites(MinecraftClient.getInstance().world, MinecraftClient.getInstance().world == null ? null : BlockPos.ORIGIN, fluid.getDefaultState());
+ int color = -1;
+ if (MinecraftClient.getInstance().world != null)
+ color = fluidRenderHandler.getFluidColor(MinecraftClient.getInstance().world, BlockPos.ORIGIN, fluid.getDefaultState());
+ Pair<Sprite, Integer> pair = new Pair<>(sprites[0], color);
+ FLUID_SPRITE_CACHE.put(fluid, pair);
+ return pair;
+ }
+
+ @Override
+ public Optional<Identifier> getIdentifier() {
+ return Optional.ofNullable(Registry.FLUID.getId(getFluid()));
+ }
+
+ @Override
+ public Type getType() {
+ return Type.FLUID;
+ }
+
+ @Override
+ public int getAmount() {
+ return amount;
+ }
+
+ @Override
+ public void setAmount(int amount) {
+ this.amount = Math.max(amount, 0);
+ if (isEmpty()) {
+ fluid = Fluids.EMPTY;
+ }
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return amount <= 0 || fluid == Fluids.EMPTY;
+ }
+
+ @Override
+ public Entry toEntry() {
+ return Entry.create(getFluid());
+ }
+
+ @Override
+ public EntryStack copy() {
+ EntryStack stack = EntryStack.create(fluid, amount);
+ for (Map.Entry<Settings, Object> entry : getSettings().entrySet()) {
+ stack.setting(entry.getKey(), entry.getValue());
+ }
+ return stack;
+ }
+
+ @Override
+ public Object getObject() {
+ return fluid;
+ }
+
+ @Override
+ public boolean equalsIgnoreTagsAndAmount(EntryStack stack) {
+ if (stack.getType() != Type.FLUID)
+ return false;
+ return fluid == stack.getFluid();
+ }
+
+ @Override
+ public boolean equalsIgnoreTags(EntryStack stack) {
+ if (stack.getType() != Type.FLUID)
+ return false;
+ return fluid == stack.getFluid() && amount == stack.getAmount();
+ }
+
+ @Override
+ public boolean equalsIgnoreAmount(EntryStack stack) {
+ if (stack.getType() != Type.FLUID)
+ return false;
+ return fluid == stack.getFluid();
+ }
+
+ @Override
+ public boolean equalsAll(EntryStack stack) {
+ if (stack.getType() != Type.FLUID)
+ return false;
+ return fluid == stack.getFluid() && amount == stack.getAmount();
+ }
+
+ @Nullable
+ @Override
+ public QueuedTooltip getTooltip(int mouseX, int mouseY) {
+ if (!getSetting(Settings.TOOLTIP_ENABLED).value().get() || isEmpty())
+ return null;
+ List<String> toolTip = Lists.newArrayList(EntryListWidget.tryGetEntryStackName(this));
+ toolTip.addAll(getSetting(Settings.TOOLTIP_APPEND_EXTRA).value().apply(this));
+ if (getSetting(Settings.TOOLTIP_APPEND_MOD).value().get() && RoughlyEnoughItemsCore.getConfigManager().getConfig().shouldAppendModNames()) {
+ final String modString = ClientHelper.getInstance().getFormattedModFromIdentifier(Registry.FLUID.getId(fluid));
+ boolean alreadyHasMod = false;
+ for (String s : toolTip)
+ if (s.equalsIgnoreCase(modString)) {
+ alreadyHasMod = true;
+ break;
+ }
+ if (!alreadyHasMod)
+ toolTip.add(modString);
+ }
+ return QueuedTooltip.create(toolTip);
+ }
+
+ @Override
+ public void render(Rectangle bounds, int mouseX, int mouseY, float delta) {
+ if (getSetting(Settings.RENDER).value().get()) {
+ Pair<Sprite, Integer> pair = getOrLoadSprite(getFluid());
+ if (pair != null) {
+ Sprite sprite = pair.getLeft();
+ int color = pair.getRight();
+ int a = 255;
+ int r = (color >> 16 & 255);
+ int g = (color >> 8 & 255);
+ int b = (color & 255);
+ MinecraftClient.getInstance().getTextureManager().bindTexture(SpriteAtlasTexture.BLOCK_ATLAS_TEX);
+ GuiLighting.disable();
+ Tessellator tess = Tessellator.getInstance();
+ BufferBuilder bb = tess.getBufferBuilder();
+ bb.begin(7, VertexFormats.POSITION_UV_COLOR);
+ bb.vertex(bounds.getMaxX(), bounds.y, getZ()).texture(sprite.getMaxU(), sprite.getMinV()).color(r, g, b, a).next();
+ bb.vertex(bounds.x, bounds.y, getZ()).texture(sprite.getMinU(), sprite.getMinV()).color(r, g, b, a).next();
+ bb.vertex(bounds.x, bounds.getMaxY(), getZ()).texture(sprite.getMinU(), sprite.getMaxV()).color(r, g, b, a).next();
+ bb.vertex(bounds.getMaxX(), bounds.getMaxY(), getZ()).texture(sprite.getMaxU(), sprite.getMaxV()).color(r, g, b, a).next();
+ tess.draw();
+ }
+ }
+ }
+}
diff --git a/src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java b/src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java
new file mode 100644
index 000000000..9681eab24
--- /dev/null
+++ b/src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java
@@ -0,0 +1,158 @@
+/*
+ * Roughly Enough Items by Danielshe.
+ * Licensed under the MIT License.
+ */
+
+package me.shedaniel.rei.impl;
+
+import com.google.common.collect.Lists;
+import me.shedaniel.math.api.Rectangle;
+import me.shedaniel.math.compat.RenderHelper;
+import me.shedaniel.rei.RoughlyEnoughItemsCore;
+import me.shedaniel.rei.api.ClientHelper;
+import me.shedaniel.rei.api.Entry;
+import me.shedaniel.rei.api.EntryStack;
+import me.shedaniel.rei.api.ItemStackRenderOverlayHook;
+import me.shedaniel.rei.gui.widget.EntryListWidget;
+import me.shedaniel.rei.gui.widget.QueuedTooltip;
+import net.minecraft.client.MinecraftClient;
+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.registry.Registry;
+
+import javax.annotation.Nullable;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+@Deprecated
+public class ItemEntryStack extends AbstractEntryStack {
+
+ private ItemStack itemStack;
+
+ public ItemEntryStack(ItemStack itemStack) {
+ this.itemStack = itemStack;
+ }
+
+ @Override
+ public Optional<Identifier> getIdentifier() {
+ return Optional.ofNullable(Registry.ITEM.getId(getItem()));
+ }
+
+ @Override
+ public Type getType() {
+ return Type.ITEM;
+ }
+
+ @Override
+ public int getAmount() {
+ return itemStack.getCount();
+ }
+
+ @Override
+ public void setAmount(int amount) {
+ itemStack.setCount(amount);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return itemStack.isEmpty();
+ }
+
+ @Override
+ public Entry toEntry() {
+ return Entry.create(getItemStack());
+ }
+
+ @Override
+ public EntryStack copy() {
+ EntryStack stack = EntryStack.create(getItemStack().copy());
+ for (Map.Entry<Settings, Object> entry : getSettings().entrySet()) {
+ stack.setting(entry.getKey(), entry.getValue());
+ }
+ return stack;
+ }
+
+ @Override
+ public Object getObject() {
+ return itemStack;
+ }
+
+ @Override
+ public boolean equalsIgnoreTagsAndAmount(EntryStack stack) {
+ if (stack.getType() != Type.ITEM)
+ return false;
+ return itemStack.getItem() == stack.getItem();
+ }
+
+ @Override
+ public boolean equalsAll(EntryStack stack) {
+ if (stack.getType() != Type.ITEM)
+ return false;
+ if (itemStack.getItem() != stack.getItem() || getAmount() != stack.getAmount())
+ return false;
+ return ItemStack.areTagsEqual(itemStack, stack.getItemStack());
+ }
+
+ @Override
+ public boolean equalsIgnoreAmount(EntryStack stack) {
+ if (stack.getType() != Type.ITEM)
+ return false;
+ if (itemStack.getItem() != stack.getItem())
+ return false;
+ return ItemStack.areTagsEqual(itemStack, stack.getItemStack());
+ }
+
+ @Override
+ public boolean equalsIgnoreTags(EntryStack stack) {
+ if (stack.getType() != Type.ITEM)
+ return false;
+ if (itemStack.getItem() != stack.getItem())
+ return false;
+ return getAmount() == stack.getAmount();
+ }
+
+ @Nullable
+ @Override
+ public QueuedTooltip getTooltip(int mouseX, int mouseY) {
+ if (!getSetting(Settings.TOOLTIP_ENABLED).value().get() || isEmpty())
+ return null;
+ List<String> toolTip = Lists.newArrayList(EntryL