mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-13 00:37:52 +00:00
Add class to wrap IItemHandler as IInventory for easier recipe interaction. (#5522)
This commit is contained in:
1 parent
5fa732d223
commit
36470f69ad
3 files changed
+190
-5
No files matched your search
@@ -28,6 +28,7 @@ import javax.annotation.Nullable;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.resources.IResourceManager;
|
||||
@@ -36,24 +37,42 @@ import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
||||
import net.minecraftforge.common.crafting.RecipeType;
|
||||
import net.minecraftforge.items.wrapper.RecipeWrapper;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract class ForgeRecipeManager implements IResourceManagerReloadListener
|
||||
{
|
||||
/**
|
||||
* Master list of sorted recipes.
|
||||
*/
|
||||
protected final Map<RecipeType<? extends IRecipe>, List<? extends IRecipe>> sortedRecipes = Maps.newHashMap();
|
||||
|
||||
@Override
|
||||
public void onResourceManagerReload(IResourceManager resourceManager) {
|
||||
public void onResourceManagerReload(IResourceManager resourceManager)
|
||||
{
|
||||
this.sortedRecipes.clear();
|
||||
CraftingHelper.reloadConstants(resourceManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the recipes that match this type.
|
||||
* @param type A recipe type.
|
||||
* @return All recipes that are of the passed type. This list may be empty.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends IRecipe> List<T> getRecipes(RecipeType<T> type)
|
||||
{
|
||||
return (List<T>) this.sortedRecipes.computeIfAbsent(type, t -> new ArrayList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically returns a result from the first recipe that matches this inv and type.
|
||||
* Modders should probably not use this, and instead use {@link #getRecipe(IInventory, World, RecipeType)} since you get the recipe object itself.
|
||||
* @param input An inventory.
|
||||
* @param world The world.
|
||||
* @param type The type of recipe to match against.
|
||||
* @return The output of the first matching recipe, or {@link ItemStack#EMPTY} if no recipes match.
|
||||
*/
|
||||
public ItemStack getResult(IInventory input, World world, RecipeType<?> type)
|
||||
{
|
||||
for(IRecipe irecipe : getRecipes(type))
|
||||
@@ -61,7 +80,16 @@ public abstract class ForgeRecipeManager implements IResourceManagerReloadListen
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
/**
|
||||
* Used to find a matching recipe for the given inv, world, and type.
|
||||
* Since this requires an IInventory, modders can use {@link RecipeWrapper} to avoid direct implementation.
|
||||
* For crafting recipes, it is advised to still use {@link InventoryCrafting}. The dynamic vanilla recipes require they be crafted in one.
|
||||
* @param input An inventory.
|
||||
* @param world The world.
|
||||
* @param type The type of recipe to match against.
|
||||
* @return The first matching recipe.
|
||||
*/
|
||||
@Nullable
|
||||
public <T extends IRecipe> T getRecipe(IInventory input, World world, RecipeType<T> type)
|
||||
{
|
||||
for(T irecipe : getRecipes(type))
|
||||
@@ -71,7 +99,9 @@ public abstract class ForgeRecipeManager implements IResourceManagerReloadListen
|
||||
|
||||
/**
|
||||
* Modders should not use this if possible. In the context that this is used, you should already have the recipe. Do not run extra lookups using this method.
|
||||
* Use {@link IRecipe#getRemainingItems(IInventory)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public NonNullList<ItemStack> getRemainingItems(IInventory input, World world, RecipeType<?> type)
|
||||
{
|
||||
for(IRecipe irecipe : getRecipes(type))
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
package net.minecraftforge.common.extensions;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraftforge.common.crafting.RecipeType;
|
||||
import net.minecraftforge.common.crafting.VanillaRecipeTypes;
|
||||
@@ -28,7 +26,7 @@ import net.minecraftforge.common.crafting.VanillaRecipeTypes;
|
||||
public interface IForgeRecipe {
|
||||
|
||||
/**
|
||||
* Used when sorting this recipe into it's category during load, and in the default type matcher below.
|
||||
* Used when sorting this recipe into it's category during load. This type determines what class the recipe must subclass.
|
||||
* @return The type of this recipe.
|
||||
*/
|
||||
default RecipeType<? extends IRecipe> getType()
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.items.wrapper;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
|
||||
public class RecipeWrapper implements IInventory {
|
||||
|
||||
protected final IItemHandlerModifiable inv;
|
||||
protected final int width;
|
||||
protected final int height;
|
||||
|
||||
public RecipeWrapper(IItemHandlerModifiable inv, int width, int height)
|
||||
{
|
||||
this.inv = inv;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of this inventory. Must be equivalent to {@link #getHeight()} * {@link #getWidth()}.
|
||||
*/
|
||||
@Override
|
||||
public int getSizeInventory()
|
||||
{
|
||||
return getHeight() * getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stack in this slot. This stack should be a modifiable reference, not a copy of a stack in your inventory.
|
||||
*/
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int slot)
|
||||
{
|
||||
return inv.getStackInSlot(slot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to remove n items from the specified slot. Returns the split stack that was removed. Modifies the inventory.
|
||||
*/
|
||||
@Override
|
||||
public ItemStack decrStackSize(int slot, int count)
|
||||
{
|
||||
ItemStack stack = inv.getStackInSlot(slot);
|
||||
return stack.isEmpty() ? ItemStack.EMPTY : stack.split(count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the contents of this slot to the provided stack.
|
||||
*/
|
||||
@Override
|
||||
public void setInventorySlotContents(int slot, ItemStack stack)
|
||||
{
|
||||
inv.setStackInSlot(slot, stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the height of this inventory.
|
||||
*/
|
||||
@Override
|
||||
public int getHeight()
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the width of this inventory.
|
||||
*/
|
||||
@Override
|
||||
public int getWidth()
|
||||
{
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the stack contained in this slot from the underlying handler, and returns it.
|
||||
*/
|
||||
@Override
|
||||
public ItemStack removeStackFromSlot(int index)
|
||||
{
|
||||
ItemStack s = getStackInSlot(index);
|
||||
if(s.isEmpty()) return ItemStack.EMPTY;
|
||||
setInventorySlotContents(index, ItemStack.EMPTY);
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty()
|
||||
{
|
||||
for(int i = 0; i < inv.getSlots(); i++)
|
||||
{
|
||||
if(!inv.getStackInSlot(i).isEmpty()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValidForSlot(int slot, ItemStack stack)
|
||||
{
|
||||
return inv.isItemValid(slot, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear()
|
||||
{
|
||||
for(int i = 0; i < inv.getSlots(); i++)
|
||||
{
|
||||
inv.setStackInSlot(i, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
//The following methods are never used by vanilla in crafting. They are defunct as mods need not override them.
|
||||
@Override
|
||||
public int getInventoryStackLimit() { return 0; }
|
||||
@Override
|
||||
public void markDirty() {}
|
||||
@Override
|
||||
public boolean isUsableByPlayer(EntityPlayer player) { return false; }
|
||||
@Override
|
||||
public void openInventory(EntityPlayer player) {}
|
||||
@Override
|
||||
public void closeInventory(EntityPlayer player) {}
|
||||
@Override
|
||||
public int getField(int id) { return 0; }
|
||||
@Override
|
||||
public void setField(int id, int value) {}
|
||||
@Override
|
||||
public int getFieldCount() { return 0; }
|
||||
@Override
|
||||
public ITextComponent getName() { return null; }
|
||||
@Override
|
||||
public boolean hasCustomName() { return false; }
|
||||
@Override
|
||||
public ITextComponent getCustomName() { return null; }
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user