/* * This file is licensed under the MIT License, part of Roughly Enough Items. * Copyright (c) 2018, 2019, 2020 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; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.widgets.Tooltip; import me.shedaniel.rei.impl.EmptyEntryStack; import me.shedaniel.rei.impl.FluidEntryStack; import me.shedaniel.rei.impl.ItemEntryStack; import net.minecraft.client.resource.language.I18n; import net.minecraft.fluid.Fluid; import net.minecraft.item.BucketItem; import net.minecraft.item.Item; import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.StringNbtReader; import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.function.Function; import java.util.function.Supplier; @SuppressWarnings("deprecation") public interface EntryStack { static EntryStack empty() { return EmptyEntryStack.EMPTY; } static EntryStack create(Fluid fluid) { return new FluidEntryStack(fluid); } static EntryStack create(Fluid fluid, int amount) { return new FluidEntryStack(fluid, amount); } static EntryStack create(ItemStack stack) { return new ItemEntryStack(stack); } static EntryStack create(ItemConvertible item) { return create(new ItemStack(item)); } @ApiStatus.Internal static EntryStack readFromJson(JsonElement jsonElement) { try { JsonObject obj = jsonElement.getAsJsonObject(); switch (obj.getAsJsonPrimitive("type").getAsString()) { case "stack": return EntryStack.create(ItemStack.fromTag(StringNbtReader.parse(obj.get("nbt").getAsString()))); case "fluid": return EntryStack.create(Registry.FLUID.get(Identifier.tryParse(obj.get("id").getAsString()))); case "empty": return EntryStack.empty(); default: throw new IllegalArgumentException("Invalid Entry Type!"); } } catch (Exception e) { e.printStackTrace(); return EntryStack.empty(); } } @ApiStatus.Internal @Nullable default JsonElement toJson() { try { switch (getType()) { case ITEM: JsonObject obj1 = new JsonObject(); obj1.addProperty("type", "stack"); obj1.addProperty("nbt", getItemStack().toTag(new CompoundTag()).toString()); return obj1; case FLUID: Optional optionalIdentifier = getIdentifier(); if (!optionalIdentifier.isPresent()) throw new NullPointerException("Invalid Fluid: " + toString()); JsonObject obj2 = new JsonObject(); obj2.addProperty("type", "fluid"); obj2.addProperty("id", optionalIdentifier.get().toString()); return obj2; case EMPTY: JsonObject obj3 = new JsonObject(); obj3.addProperty("type", "empty"); return obj3; default: throw new IllegalArgumentException("Invalid Entry Type!"); } } catch (Exception e) { e.printStackTrace(); return null; } } static EntryStack copyFluidToBucket(EntryStack stack) { if (stack.getType() != Type.FLUID) throw new IllegalArgumentException("EntryStack must be fluid!"); Fluid fluid = stack.getFluid(); Item item = fluid.getBucketItem(); if (item == null) return EntryStack.empty(); return EntryStack.create(item); } static EntryStack copyBucketToFluid(EntryStack stack) { if (stack.getType() != Type.ITEM) throw new IllegalArgumentException("EntryStack must be item!"); Item item = stack.getItem(); if (item instanceof BucketItem) return EntryStack.create(((BucketItem) item).fluid, 1000); return EntryStack.empty(); } Optional getIdentifier(); EntryStack.Type getType(); int getAmount(); void setAmount(int amount); boolean isEmpty(); EntryStack copy(); Object getObject(); boolean equals(EntryStack stack, boolean ignoreTags, boolean ignoreAmount); boolean equalsIgnoreTagsAndAmount(EntryStack stack); boolean equalsIgnoreTags(EntryStack stack); boolean equalsIgnoreAmount(EntryStack stack); boolean equalsAll(EntryStack stack); /** * {@link #hashCode()} for {@link #equalsAll(EntryStack)}. */ default int hashOfAll() { return hashCode(); } /** * {@link #hashCode()} for {@link #equalsIgnoreAmount(EntryStack)} */ default int hashIgnoreAmount() { return hashCode(); } /** * {@link #hashCode()} for {@link #equalsIgnoreTags(EntryStack)} */ default int hashIgnoreTags() { return hashCode(); } /** * {@link #hashCode()} for {@link #equalsIgnoreTagsAndAmount(EntryStack)} */ default int hashIgnoreAmountAndTags() { return hashCode(); } int getZ(); void setZ(int z); default ItemStack getItemStack() { if (getType() == Type.ITEM) return (ItemStack) getObject(); return null; } default Item getItem() { if (getType() == Type.ITEM) return ((ItemStack) getObject()).getItem(); return null; } default Fluid getFluid() { if (getType() == Type.FLUID) return (Fluid) getObject(); return null; } EntryStack setting(Settings settings, T value); EntryStack removeSetting(Settings settings); EntryStack clearSettings(); default EntryStack addSetting(Settings settings, T value) { return setting(settings, value); } T get(Settings settings); @Nullable default Tooltip getTooltip(Point mouse) { return null; } void render(Rectangle bounds, int mouseX, int mouseY, float delta); enum Type { ITEM, FLUID, EMPTY, RENDER } class Settings { public static final Supplier TRUE = () -> true; public static final Supplier FALSE = () -> false; public static final Settings> RENDER = new Settings<>(TRUE); public static final Settings> CHECK_TAGS = new Settings<>(FALSE); public static final Settings> CHECK_AMOUNT = new Settings<>(FALSE); public static final Settings> TOOLTIP_ENABLED = new Settings<>(TRUE); public static final Settings> TOOLTIP_APPEND_MOD = new Settings<>(TRUE); public static final Settings> RENDER_COUNTS = new Settings<>(TRUE); public static final Settings>> TOOLTIP_APPEND_EXTRA = new Settings<>(stack -> Collections.emptyList()); public static final Settings> COUNTS = new Settings<>(stack -> null); private T defaultValue; public Settings(T defaultValue) { this.defaultValue = defaultValue; } public T getDefaultValue() { return defaultValue; } public static class Item { public static final Settings> RENDER_ENCHANTMENT_GLINT = new Settings<>(TRUE); private Item() { } } public static class Fluid { // Return null to disable public static final Settings> AMOUNT_TOOLTIP = new Settings<>(stack -> I18n.translate("tooltip.rei.fluid_amount", stack.getAmount())); private Fluid() { } } } }