Utils ported

This commit is contained in:
Sebastian Hartte
2020-06-28 03:41:44 +02:00
parent 7c28a71e10
commit fee5b7fdfc
204 changed files with 1371 additions and 1737 deletions
+2 -2
View File
@@ -31,8 +31,8 @@ public class BlockUpdate implements IWorldCallable<Boolean> {
@Override
public Boolean call(final World world) throws Exception {
if (world.isBlockLoaded(this.pos)) {
world.notifyNeighborsOfStateChange(this.pos, Blocks.AIR);
if (world.isChunkLoaded(this.pos)) {
world.updateNeighborsAlways(this.pos, Blocks.AIR);
}
return true;
+57
View File
@@ -0,0 +1,57 @@
package appeng.util;
import com.mojang.authlib.GameProfile;
import io.netty.util.concurrent.CompleteFuture;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import io.netty.util.concurrent.SucceededFuture;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.NetworkSide;
import net.minecraft.network.Packet;
import net.minecraft.network.packet.c2s.play.ClientSettingsC2SPacket;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.network.ServerPlayerInteractionManager;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import javax.annotation.Nullable;
import java.util.Objects;
import java.util.UUID;
import java.util.WeakHashMap;
public class FakePlayer extends ServerPlayerEntity {
private static final WeakHashMap<World, FakePlayer> FAKE_PLAYERS = new WeakHashMap<>();
private static final GameProfile PROFILE = new GameProfile(UUID.fromString("60C173A5-E1E6-4B87-85B1-272CE424521D"), "[AppEng2]");
private FakePlayer(ServerWorld world) {
super(world.getServer(), world, PROFILE, new ServerPlayerInteractionManager(world));
}
/**
* DO NOT COPY THE PLAYER ANYWHERE!
* It will keep the world alive, always call this method if you need it.
*/
public static FakePlayer getOrCreate(ServerWorld world) {
Objects.requireNonNull(world);
final FakePlayer wrp = FAKE_PLAYERS.get(world);
if (wrp != null) {
return wrp;
}
FakePlayer p = new FakePlayer(world);
FAKE_PLAYERS.put(world, p);
return p;
}
@Override
public void tick() {
}
// FIXME: We should probably find and override all methods that access the networkHandler
}
+16 -18
View File
@@ -18,19 +18,18 @@
package appeng.util;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.util.math.Direction;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler;
import alexiil.mc.lib.attributes.item.ItemTransferable;
import alexiil.mc.lib.attributes.SearchOptions;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import alexiil.mc.lib.attributes.item.ItemAttributes;
import appeng.api.config.FuzzyMode;
import appeng.util.inv.AdaptorItemHandler;
import appeng.util.inv.AdaptorFixedInv;
import appeng.util.inv.AdaptorItemHandlerPlayerInv;
import appeng.util.inv.IInventoryDestination;
import appeng.util.inv.ItemSlot;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.Direction;
/**
* Universal Facade for other inventories. Used to conveniently interact with
@@ -40,15 +39,14 @@ import appeng.util.inv.ItemSlot;
*/
public abstract class InventoryAdaptor implements Iterable<ItemSlot> {
public static InventoryAdaptor getAdaptor(final BlockEntity te, final Direction d) {
if (te != null) {
LazyOptional<ItemTransferable> cap = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d);
// Attempt getting an IItemHandler for the given side via caps
if (cap.isPresent()) {
return new AdaptorItemHandler(cap.orElseThrow(IllegalStateException::new));
}
FixedItemInv inv = ItemAttributes.FIXED_INV.get(te.getWorld(), te.getPos().offset(d), SearchOptions.inDirection(d.getOpposite()));
if (inv == ItemAttributes.FIXED_INV.defaultValue) {
return null;
}
return null;
return new AdaptorFixedInv(inv);
}
public static InventoryAdaptor getAdaptor(final PlayerEntity te) {
@@ -65,10 +63,10 @@ public abstract class InventoryAdaptor implements Iterable<ItemSlot> {
// return what was extracted.
public abstract ItemStack removeSimilarItems(int amount, ItemStack filter, FuzzyMode fuzzyMode,
IInventoryDestination destination);
IInventoryDestination destination);
public abstract ItemStack simulateSimilarRemove(int amount, ItemStack filter, FuzzyMode fuzzyMode,
IInventoryDestination destination);
IInventoryDestination destination);
// return what isn't used...
public abstract ItemStack addItems(ItemStack toBeAdded);
+99 -119
View File
@@ -18,62 +18,9 @@
package appeng.util;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.WeakHashMap;
import javax.annotation.Nullable;
import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
import net.fabricmc.api.Environment;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.CraftingInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.*;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.EntityRayTraceResult;
import net.minecraft.util.math.RayTraceContext;
import net.minecraft.util.hit.HitResult;
import net.minecraft.text.Text;
import net.minecraft.text.LiteralText;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.text.TranslatableText;
import net.minecraft.world.World;
import net.minecraft.server.world.ServerWorld;
import net.fabricmc.api.EnvType;
import net.minecraftforge.common.util.FakePlayerFactory;
import alexiil.mc.lib.attributes.fluid.volume.FluidVolume;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.common.thread.SidedThreadGroups;
import net.minecraftforge.fml.loading.FMLEnvironment;
import net.minecraftforge.registries.ForgeRegistries;
import appeng.api.AEApi;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.config.PowerUnits;
import appeng.api.config.SearchBoxMode;
import appeng.api.config.SecurityPermissions;
import appeng.api.config.SortOrder;
import appeng.api.config.*;
import appeng.api.definitions.IItemDefinition;
import appeng.api.definitions.IMaterials;
import appeng.api.features.AEFeature;
@@ -110,6 +57,42 @@ import appeng.util.helpers.ItemComparisonHelper;
import appeng.util.helpers.P2PHelper;
import appeng.util.item.AEItemStack;
import appeng.util.prioritylist.IPartitionList;
import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.entity.Entity;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.CraftingInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.recipe.Recipe;
import net.minecraft.server.integrated.IntegratedServer;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import net.minecraft.util.Util;
import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.*;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.RayTraceContext;
import net.minecraft.world.World;
import javax.annotation.Nullable;
import java.text.DecimalFormat;
import java.util.*;
/**
* @author AlgorithmX2
@@ -121,13 +104,14 @@ public class Platform {
public static final int DEF_OFFSET = 16;
private static final boolean CLIENT_INSTALL = FMLEnvironment.dist.isClient();
private static final FabricLoader FABRIC = FabricLoader.getInstance();
private static final boolean CLIENT_INSTALL = FABRIC.getEnvironmentType() == EnvType.CLIENT;
/*
* random source, use it for item drop locations...
*/
private static final Random RANDOM_GENERATOR = new Random();
private static final WeakHashMap<World, PlayerEntity> FAKE_PLAYERS = new WeakHashMap<>();
private static final ItemComparisonHelper ITEM_COMPARISON_HELPER = new ItemComparisonHelper();
@@ -208,14 +192,17 @@ public class Platform {
* @return True if client-side classes (such as Renderers) are available.
*/
public static boolean hasClientClasses() {
return FMLEnvironment.dist.isClient();
return FABRIC.getEnvironmentType() == EnvType.CLIENT;
}
/*
* returns true if the code is on the client.
*/
public static boolean isClient() {
return Thread.currentThread().getThreadGroup() != SidedThreadGroups.SERVER;
// FIXME: Move this to the proxy so it will work on a dedicated server
MinecraftClient client = MinecraftClient.getInstance();
IntegratedServer server = client.getServer();
return server == null || Thread.currentThread() != server.getThread();
}
/*
@@ -229,7 +216,7 @@ public class Platform {
if (!dc.isInWorld(player.world)) {
return false;
}
return player.world.canMineBlockBody(player, dc.getPos());
return player.world.canPlayerModifyAt(player, dc.getPos());
}
public static boolean checkPermissions(final PlayerEntity player, final Object accessInterface,
@@ -251,8 +238,8 @@ public class Platform {
final ISecurityGrid sg = g.getCache(ISecurityGrid.class);
if (!sg.hasPermission(player, requiredPermission)) {
player.sendMessage(new TranslatableText("appliedenergistics2.permission_denied")
.applyTextStyle(TextFormatting.RED));
player.sendSystemMessage(new TranslatableText("appliedenergistics2.permission_denied")
.formatted(Formatting.RED), Util.NIL_UUID);
// FIXME trace logging?
return false;
}
@@ -275,7 +262,7 @@ public class Platform {
final BlockState state = w.getBlockState(pos);
final BlockEntity tileEntity = w.getBlockEntity(pos);
List<ItemStack> out = Block.getDrops(state, serverWorld, pos, tileEntity);
List<ItemStack> out = Block.getDroppedStacks(state, serverWorld, pos, tileEntity);
return out.toArray(new ItemStack[0]);
}
@@ -294,7 +281,7 @@ public class Platform {
final double offset_z = (getRandomInt() % 32 - 16) / 82;
final ItemEntity ei = new ItemEntity(w, 0.5 + offset_x + pos.getX(),
0.5 + offset_y + pos.getY(), 0.2 + offset_z + pos.getZ(), i.copy());
w.addEntity(ei);
w.spawnEntity(ei);
}
}
}
@@ -305,7 +292,7 @@ public class Platform {
* returns true if the code is on the server.
*/
public static boolean isServer() {
return Thread.currentThread().getThreadGroup() == SidedThreadGroups.SERVER;
return !isClient();
}
public static int getRandomInt() {
@@ -329,9 +316,9 @@ public class Platform {
}
try {
TooltipContext.TooltipFlags tooltipFlag = MinecraftClient.getInstance().gameSettings.advancedItemTooltips
? TooltipContext.TooltipFlags.ADVANCED
: TooltipContext.TooltipFlags.NORMAL;
TooltipContext tooltipFlag = MinecraftClient.getInstance().options.advancedItemTooltips
? TooltipContext.Default.ADVANCED
: TooltipContext.Default.NORMAL;
return itemStack.getTooltip(MinecraftClient.getInstance().player, tooltipFlag);
} catch (final Exception errB) {
return Collections.emptyList();
@@ -352,13 +339,13 @@ public class Platform {
return "** Null";
}
final Identifier n = ForgeRegistries.FLUIDS.getKey(fs.getFluidStack().getFluid());
return n == null ? "** Null" : n.getNamespace();
final Identifier n = Registry.FLUID.getId(fs.getFluidStack().getRawFluid());
return n == Registry.FLUID.getDefaultId() ? "** Null" : n.getNamespace();
}
public static String getModName(String modId) {
return "" + TextFormatting.BLUE + TextFormatting.ITALIC
+ ModList.get().getModContainerById(modId).map(mc -> mc.getModInfo().getDisplayName()).orElse(null);
return "" + Formatting.BLUE + Formatting.ITALIC
+ FABRIC.getModContainer(modId).map(mc -> mc.getMetadata().getName()).orElse(null);
}
public static Text getItemDisplayName(final Object o) {
@@ -399,11 +386,7 @@ public class Platform {
} else {
return new LiteralText("**Invalid Object");
}
Text n = fluidStack.getName();
if (n == null) {
n = new TranslatableText(fluidStack.getTranslationKey());
}
return n;
return fluidStack.getName();
}
public static boolean isWrench(final PlayerEntity player, final ItemStack eq, final BlockPos pos) {
@@ -443,19 +426,6 @@ public class Platform {
return false;
}
public static PlayerEntity getPlayer(final ServerWorld w) {
Objects.requireNonNull(w);
final PlayerEntity wrp = FAKE_PLAYERS.get(w);
if (wrp != null) {
return wrp;
}
final PlayerEntity p = FakePlayerFactory.getMinecraft(w);
FAKE_PLAYERS.put(w, p);
return p;
}
/**
* Returns a random element from the given collection.
*
@@ -664,17 +634,18 @@ public class Platform {
}
public static LookDirection getPlayerRay(final PlayerEntity playerIn) {
double reachDistance = playerIn.getAttribute(PlayerEntity.REACH_DISTANCE).getValue();
// FIXME this currently cant be modded in Fabric, see net.minecraft.server.network.ServerPlayerInteractionManager.processBlockBreakingAction
double reachDistance = 36.0D;
return getPlayerRay(playerIn, reachDistance);
}
public static LookDirection getPlayerRay(final PlayerEntity playerIn, double reachDistance) {
final double x = playerIn.prevPosX + (playerIn.getPosX() - playerIn.prevPosX);
final double y = playerIn.prevPosY + (playerIn.getPosY() - playerIn.prevPosY) + playerIn.getEyeHeight();
final double z = playerIn.prevPosZ + (playerIn.getPosZ() - playerIn.prevPosZ);
final double x = playerIn.prevX + (playerIn.getX() - playerIn.prevX);
final double y = playerIn.prevY + (playerIn.getY() - playerIn.prevY) + playerIn.getEyeHeight(playerIn.getPose());
final double z = playerIn.prevZ + (playerIn.getZ() - playerIn.prevZ);
final float playerPitch = playerIn.prevRotationPitch + (playerIn.pitch - playerIn.prevRotationPitch);
final float playerYaw = playerIn.prevRotationYaw + (playerIn.rotationYaw - playerIn.prevRotationYaw);
final float playerPitch = playerIn.prevPitch + (playerIn.pitch - playerIn.prevPitch);
final float playerYaw = playerIn.prevYaw + (playerIn.yaw - playerIn.prevYaw);
final float yawRayX = MathHelper.sin(-playerYaw * 0.017453292f - (float) Math.PI);
final float yawRayZ = MathHelper.cos(-playerYaw * 0.017453292f - (float) Math.PI);
@@ -694,11 +665,11 @@ public class Platform {
final World w = p.getEntityWorld();
final float f = 1.0F;
float f1 = p.prevRotationPitch + (p.pitch - p.prevRotationPitch) * f;
final float f2 = p.prevRotationYaw + (p.rotationYaw - p.prevRotationYaw) * f;
final double d0 = p.prevPosX + (p.getPosX() - p.prevPosX) * f;
final double d1 = p.prevPosY + (p.getPosY() - p.prevPosY) * f + 1.62D - p.getOffsetY();
final double d2 = p.prevPosZ + (p.getPosZ() - p.prevPosZ) * f;
float f1 = p.prevPitch + (p.pitch - p.prevPitch) * f;
final float f2 = p.prevYaw + (p.yaw - p.prevYaw) * f;
final double d0 = p.prevX + (p.getX() - p.prevX) * f;
final double d1 = p.prevY + (p.getY() - p.prevY) * f + 1.62D - p.getHeightOffset();
final double d2 = p.prevZ + (p.getZ() - p.prevZ) * f;
final Vec3d vec3 = new Vec3d(d0, d1, d2);
final float f3 = MathHelper.cos(-f2 * 0.017453292F - (float) Math.PI);
final float f4 = MathHelper.sin(-f2 * 0.017453292F - (float) Math.PI);
@@ -712,27 +683,27 @@ public class Platform {
final Box bb = new Box(Math.min(vec3.x, vec31.x), Math.min(vec3.y, vec31.y),
Math.min(vec3.z, vec31.z), Math.max(vec3.x, vec31.x), Math.max(vec3.y, vec31.y),
Math.max(vec3.z, vec31.z)).grow(16, 16, 16);
Math.max(vec3.z, vec31.z)).expand(16, 16, 16);
Entity entity = null;
double closest = 9999999.0D;
if (hitEntities) {
final List<Entity> list = w.getEntitiesWithinAABBExcludingEntity(p, bb);
final List<Entity> list = w.getEntities(p, bb);
for (final Entity entity1 : list) {
if (entity1.isAlive() && entity1 != p && !(entity1 instanceof ItemEntity)) {
// prevent killing / flying of mounts.
if (entity1.isRidingOrBeingRiddenBy(p)) {
if (entity1.isConnectedThroughVehicle(p)) {
continue;
}
f1 = 0.3F;
// FIXME: Three different bounding boxes available, should double-check
final Box boundingBox = entity1.getBoundingBox().grow(f1, f1, f1);
final Box boundingBox = entity1.getBoundingBox().expand(f1, f1, f1);
final Vec3d rtResult = boundingBox.rayTrace(vec3, vec31).orElse(null);
if (rtResult != null) {
final double nd = vec3.squareDistanceTo(rtResult);
final double nd = vec3.squaredDistanceTo(rtResult);
if (nd < closest) {
entity = entity1;
@@ -749,14 +720,14 @@ public class Platform {
if (hitBlocks) {
vec = new Vec3d(d0, d1, d2);
// FIXME: passing p as entity here might be incorrect
pos = w.rayTraceBlocks(new RayTraceContext(vec3, vec31, RayTraceContext.BlockMode.COLLIDER,
RayTraceContext.FluidMode.ANY, p));
pos = w.rayTrace(new RayTraceContext(vec3, vec31, RayTraceContext.ShapeType.COLLIDER,
RayTraceContext.FluidHandling.ANY, p));
}
if (entity != null && pos != null && pos.getHitVec().squareDistanceTo(vec) > closest) {
pos = new EntityRayTraceResult(entity);
if (entity != null && pos != null && pos.getPos().squaredDistanceTo(vec) > closest) {
pos = new EntityHitResult(entity);
} else if (entity != null && pos == null) {
pos = new EntityRayTraceResult(entity);
pos = new EntityHitResult(entity);
}
return pos;
@@ -1009,7 +980,7 @@ public class Platform {
break;
}
player.setLocationAndAngles(tile.getPos().getX() + 0.5, tile.getPos().getY() + 0.5, tile.getPos().getZ() + 0.5,
player.refreshPositionAndAngles(tile.getPos().getX() + 0.5, tile.getPos().getY() + 0.5, tile.getPos().getZ() + 0.5,
yaw, pitch);
}
@@ -1035,7 +1006,7 @@ public class Platform {
}
public static ItemStack extractItemsByRecipe(final IEnergySource energySrc, final IActionSource mySrc,
final IMEMonitor<IAEItemStack> src, final World w, final IRecipe<CraftingInventory> r,
final IMEMonitor<IAEItemStack> src, final World w, final Recipe<CraftingInventory> r,
final ItemStack output, final CraftingInventory ci, final ItemStack providedTemplate, final int slot,
final IItemList<IAEItemStack> items, final Actionable realForFake,
final IPartitionList<IAEItemStack> filter) {
@@ -1073,8 +1044,8 @@ public class Platform {
// )
final ItemStack cp = sh.copy();
cp.setCount(1);
ci.setInventorySlotContents(slot, cp);
if (r.matches(ci, w) && ItemStack.areItemsEqual(r.getCraftingResult(ci), output)) {
ci.setStack(slot, cp);
if (r.matches(ci, w) && ItemStack.areItemsEqual(r.craft(ci), output)) {
final IAEItemStack ax = x.copy();
ax.setStackSize(1);
if (filter == null || filter.isListed(ax)) {
@@ -1085,7 +1056,7 @@ public class Platform {
}
}
}
ci.setInventorySlotContents(slot, providedTemplate);
ci.setStack(slot, providedTemplate);
}
}
}
@@ -1098,13 +1069,13 @@ public class Platform {
* remains when the item is used for crafting, i.E. the empty bucket for a
* bucket of water.
*/
public static ItemStack getContainerItem(final ItemStack stackInSlot) {
public static ItemStack getRecipeRemainder(final ItemStack stackInSlot) {
if (stackInSlot == null) {
return ItemStack.EMPTY;
}
final Item i = stackInSlot.getItem();
if (i == null || !i.hasContainerItem(stackInSlot)) {
if (i == null || !i.hasRecipeRemainder()) {
if (stackInSlot.getCount() > 1) {
stackInSlot.setCount(stackInSlot.getCount() - 1);
return stackInSlot;
@@ -1112,7 +1083,7 @@ public class Platform {
return ItemStack.EMPTY;
}
ItemStack ci = i.getContainerItem(stackInSlot.copy());
ItemStack ci = new ItemStack(i.getRecipeRemainder());
if (!ci.isEmpty() && ci.isDamageable() && ci.getDamage() == ci.getMaxDamage()) {
ci = ItemStack.EMPTY;
}
@@ -1148,7 +1119,7 @@ public class Platform {
public static float getEyeOffset(final PlayerEntity player) {
assert player.world.isClient : "Valid only on client";
// FIXME: The entire premise of this seems broken
return (float) (player.getPosY() + player.getEyeHeight() - /* FIXME player.getDefaultEyeHeight() */ 1.62F);
return (float) player.getEyeY() - 1.62F;
}
public static boolean isRecipePrioritized(final ItemStack what) {
@@ -1172,4 +1143,13 @@ public class Platform {
return true;
}
public static ItemStack copyStackWithSize(ItemStack stack, int size) {
if (!stack.isEmpty() && size > 0) {
ItemStack copy = stack.copy();
copy.setCount(size);
return copy;
}
return ItemStack.EMPTY;
}
}
@@ -18,48 +18,42 @@
package appeng.util.helpers;
import alexiil.mc.lib.attributes.item.ItemTransferable;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import net.minecraft.inventory.CraftingInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandlerModifiable;
public class ItemHandlerUtil {
private ItemHandlerUtil() {
}
public static void setStackInSlot(final ItemTransferable inv, final int slot, final ItemStack stack) {
if (inv instanceof IItemHandlerModifiable) {
((IItemHandlerModifiable) inv).setStackInSlot(slot, stack);
} else {
inv.extractItem(slot, Integer.MAX_VALUE, false);
inv.insertItem(slot, stack, false);
}
public static void setStackInSlot(final FixedItemInv inv, final int slot, final ItemStack stack) {
inv.forceSetInvStack(slot, stack);
}
public static void clear(final ItemTransferable inv) {
for (int x = 0; x < inv.getSlots(); x++) {
public static void clear(final FixedItemInv inv) {
for (int x = 0; x < inv.getSlotCount(); x++) {
setStackInSlot(inv, x, ItemStack.EMPTY);
}
}
public static boolean isEmpty(final ItemTransferable inv) {
for (int x = 0; x < inv.getSlots(); x++) {
if (!inv.getStackInSlot(x).isEmpty()) {
public static boolean isEmpty(final FixedItemInv inv) {
for (int x = 0; x < inv.getSlotCount(); x++) {
if (!inv.getInvStack(x).isEmpty()) {
return false;
}
}
return true;
}
public static void copy(final ItemTransferable from, final ItemTransferable to, boolean deepCopy) {
for (int i = 0; i < Math.min(from.getSlots(), to.getSlots()); ++i) {
setStackInSlot(to, i, deepCopy ? from.getStackInSlot(i).copy() : from.getStackInSlot(i));
public static void copy(final FixedItemInv from, final FixedItemInv to, boolean deepCopy) {
for (int i = 0; i < Math.min(from.getSlotCount(), to.getSlotCount()); ++i) {
setStackInSlot(to, i, deepCopy ? from.getInvStack(i).copy() : from.getInvStack(i));
}
}
public static void copy(final CraftingInventory from, final ItemTransferable to, boolean deepCopy) {
for (int i = 0; i < Math.min(from.getSizeInventory(), to.getSlots()); ++i) {
setStackInSlot(to, i, deepCopy ? from.getStackInSlot(i).copy() : from.getStackInSlot(i));
public static void copy(final CraftingInventory from, final FixedItemInv to, boolean deepCopy) {
for (int i = 0; i < Math.min(from.size(), to.getSlotCount()); ++i) {
setStackInSlot(to, i, deepCopy ? from.getStack(i).copy() : from.getStack(i));
}
}
}
@@ -0,0 +1,134 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 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, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 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 Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.util.inv;
import alexiil.mc.lib.attributes.Simulation;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import alexiil.mc.lib.attributes.item.ItemTransferable;
import alexiil.mc.lib.attributes.item.filter.ItemFilter;
import appeng.api.config.FuzzyMode;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import net.minecraft.item.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.Iterator;
public class AdaptorFixedInv extends InventoryAdaptor {
protected final FixedItemInv itemHandler;
protected final ItemTransferable transferable;
public AdaptorFixedInv(FixedItemInv itemHandler) {
this.itemHandler = itemHandler;
this.transferable = itemHandler.getTransferable();
}
@Override
public boolean hasSlots() {
return this.itemHandler.getSlotCount() > 0;
}
@Override
public ItemStack removeItems(int amount, ItemStack filter, IInventoryDestination destination) {
ItemFilter itemFilter = createExactFilter(filter, destination);
return this.transferable.attemptExtraction(itemFilter, amount, Simulation.ACTION);
}
@Override
public ItemStack simulateRemove(int amount, ItemStack filter, IInventoryDestination destination) {
ItemFilter itemFilter = createExactFilter(filter, destination);
return this.transferable.attemptExtraction(itemFilter, amount, Simulation.SIMULATE);
}
@NotNull
private ItemFilter createExactFilter(ItemStack filter, IInventoryDestination destination) {
ItemFilter itemFilter = destination != null ? destination::canInsert : stack -> true;
if (!filter.isEmpty()) {
if (destination != null) {
itemFilter = stack -> Platform.itemComparisons().isSameItem(stack, filter) && destination.canInsert(stack);
} else {
itemFilter = stack -> Platform.itemComparisons().isSameItem(stack, filter);
}
}
return itemFilter;
}
@NotNull
private ItemFilter createFuzzyFilter(ItemStack filter, FuzzyMode fuzzyMode, IInventoryDestination destination) {
ItemFilter itemFilter = destination != null ? destination::canInsert : stack -> true;
if (!filter.isEmpty()) {
if (destination != null) {
itemFilter = stack -> Platform.itemComparisons().isFuzzyEqualItem(stack, filter, fuzzyMode) && destination.canInsert(stack);
} else {
itemFilter = stack -> Platform.itemComparisons().isFuzzyEqualItem(stack, filter, fuzzyMode);
}
}
return itemFilter;
}
/**
* For fuzzy extract, we will only ever extract one slot, since we're afraid of
* merging two item stacks with different damage values.
*/
@Override
public ItemStack removeSimilarItems(int amount, ItemStack filter, FuzzyMode fuzzyMode,
IInventoryDestination destination) {
ItemFilter itemFilter = createFuzzyFilter(filter, fuzzyMode, destination);
return this.transferable.attemptExtraction(itemFilter, amount, Simulation.ACTION);
}
@Override
public ItemStack simulateSimilarRemove(int amount, ItemStack filter, FuzzyMode fuzzyMode,
IInventoryDestination destination) {
ItemFilter itemFilter = createFuzzyFilter(filter, fuzzyMode, destination);
return this.transferable.attemptExtraction(itemFilter, amount, Simulation.SIMULATE);
}
@Override
public ItemStack addItems(ItemStack toBeAdded) {
return this.addItems(toBeAdded, false);
}
@Override
public ItemStack simulateAdd(ItemStack toBeSimulated) {
return this.addItems(toBeSimulated, true);
}
protected ItemStack addItems(final ItemStack itemsToAdd, final boolean simulate) {
if (itemsToAdd.isEmpty()) {
return ItemStack.EMPTY;
}
return this.transferable.attemptInsertion(itemsToAdd, simulate ? Simulation.SIMULATE : Simulation.ACTION);
}
@Override
public boolean containsItems() {
return !transferable.attemptAnyExtraction(1, Simulation.SIMULATE).isEmpty();
}
@Override
public Iterator<ItemSlot> iterator() {
return new ItemHandlerIterator(this.itemHandler);
}
}
@@ -1,226 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 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, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 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 Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.util.inv;
import java.util.Iterator;
import net.minecraft.item.ItemStack;
import alexiil.mc.lib.attributes.item.ItemTransferable;
import appeng.api.config.FuzzyMode;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
public class AdaptorItemHandler extends InventoryAdaptor {
protected final ItemTransferable itemHandler;
public AdaptorItemHandler(ItemTransferable itemHandler) {
this.itemHandler = itemHandler;
}
@Override
public boolean hasSlots() {
return this.itemHandler.getSlots() > 0;
}
@Override
public ItemStack removeItems(int amount, ItemStack filter, IInventoryDestination destination) {
int slots = this.itemHandler.getSlots();
ItemStack rv = ItemStack.EMPTY;
for (int slot = 0; slot < slots && amount > 0; slot++) {
final ItemStack is = this.itemHandler.getStackInSlot(slot);
if (is.isEmpty() || (!filter.isEmpty() && !Platform.itemComparisons().isSameItem(is, filter))) {
continue;
}
if (destination != null) {
ItemStack extracted = this.itemHandler.extractItem(slot, amount, true);
if (extracted.isEmpty()) {
continue;
}
if (!destination.canInsert(extracted)) {
continue;
}
}
// Attempt extracting it
ItemStack extracted = this.itemHandler.extractItem(slot, amount, false);
if (extracted.isEmpty()) {
continue;
}
if (rv.isEmpty()) {
// Use the first stack as a template for the result
rv = extracted;
filter = extracted;
amount -= extracted.getCount();
} else {
// Subsequent stacks will just increase the extracted size
rv.grow(extracted.getCount());
amount -= extracted.getCount();
}
}
return rv;
}
@Override
public ItemStack simulateRemove(int amount, ItemStack filter, IInventoryDestination destination) {
int slots = this.itemHandler.getSlots();
ItemStack rv = ItemStack.EMPTY;
for (int slot = 0; slot < slots && amount > 0; slot++) {
final ItemStack is = this.itemHandler.getStackInSlot(slot);
if (!is.isEmpty() && (filter.isEmpty() || Platform.itemComparisons().isSameItem(is, filter))) {
ItemStack extracted = this.itemHandler.extractItem(slot, amount, true);
if (extracted.isEmpty()) {
continue;
}
if (destination != null) {
if (!destination.canInsert(extracted)) {
continue;
}
}
if (rv.isEmpty()) {
// Use the first stack as a template for the result
rv = extracted.copy();
filter = extracted;
amount -= extracted.getCount();
} else {
// Subsequent stacks will just increase the extracted size
rv.grow(extracted.getCount());
amount -= extracted.getCount();
}
}
}
return rv;
}
/**
* For fuzzy extract, we will only ever extract one slot, since we're afraid of
* merging two item stacks with different damage values.
*/
@Override
public ItemStack removeSimilarItems(int amount, ItemStack filter, FuzzyMode fuzzyMode,
IInventoryDestination destination) {
int slots = this.itemHandler.getSlots();
ItemStack extracted = ItemStack.EMPTY;
for (int slot = 0; slot < slots && extracted.isEmpty(); slot++) {
final ItemStack is = this.itemHandler.getStackInSlot(slot);
if (is.isEmpty()
|| (!filter.isEmpty() && !Platform.itemComparisons().isFuzzyEqualItem(is, filter, fuzzyMode))) {
continue;
}
if (destination != null) {
ItemStack simulated = this.itemHandler.extractItem(slot, amount, true);
if (simulated.isEmpty()) {
continue;
}
if (!destination.canInsert(simulated)) {
continue;
}
}
// Attempt extracting it
extracted = this.itemHandler.extractItem(slot, amount, false);
}
return extracted;
}
@Override
public ItemStack simulateSimilarRemove(int amount, ItemStack filter, FuzzyMode fuzzyMode,
IInventoryDestination destination) {
int slots = this.itemHandler.getSlots();
ItemStack extracted = ItemStack.EMPTY;
for (int slot = 0; slot < slots && extracted.isEmpty(); slot++) {
final ItemStack is = this.itemHandler.getStackInSlot(slot);
if (is.isEmpty()
|| (!filter.isEmpty() && !Platform.itemComparisons().isFuzzyEqualItem(is, filter, fuzzyMode))) {
continue;
}
// Attempt extracting it
extracted = this.itemHandler.extractItem(slot, amount, true);
if (!extracted.isEmpty() && destination != null) {
if (!destination.canInsert(extracted)) {
extracted = ItemStack.EMPTY; // Keep on looking...
}
}
}
return extracted;
}
@Override
public ItemStack addItems(ItemStack toBeAdded) {
return this.addItems(toBeAdded, false);
}
@Override
public ItemStack simulateAdd(ItemStack toBeSimulated) {
return this.addItems(toBeSimulated, true);
}
protected ItemStack addItems(final ItemStack itemsToAdd, final boolean simulate) {
if (itemsToAdd.isEmpty()) {
return ItemStack.EMPTY;
}
ItemStack left = itemsToAdd.copy();
for (int slot = 0; slot < this.itemHandler.getSlots(); slot++) {
left = this.itemHandler.insertItem(slot, left, simulate);
if (left.isEmpty()) {
return ItemStack.EMPTY;
}
}
return left;
}
@Override
public boolean containsItems() {
int slots = this.itemHandler.getSlots();
for (int slot = 0; slot < slots; slot++) {
if (!this.itemHandler.getStackInSlot(slot).isEmpty()) {
return true;
}
}
return false;
}
@Override
public Iterator<ItemSlot> iterator() {
return new ItemHandlerIterator(this.itemHandler);
}
}
@@ -18,15 +18,16 @@
package appeng.util.inv;
import alexiil.mc.lib.attributes.Simulation;
import alexiil.mc.lib.attributes.item.compat.FixedInventoryVanillaWrapper;
import appeng.util.Platform;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.wrapper.PlayerMainInvWrapper;
import appeng.util.Platform;
public class AdaptorItemHandlerPlayerInv extends AdaptorFixedInv {
public class AdaptorItemHandlerPlayerInv extends AdaptorItemHandler {
public AdaptorItemHandlerPlayerInv(final PlayerEntity playerInv) {
super(new PlayerMainInvWrapper(playerInv.inventory));
super(new FixedInventoryVanillaWrapper(playerInv.inventory));
}
/**
@@ -38,27 +39,23 @@ public class AdaptorItemHandlerPlayerInv extends AdaptorItemHandler {
return ItemStack.EMPTY;
}
Simulation sim = simulate ? Simulation.SIMULATE : Simulation.ACTION;
ItemStack left = itemsToAdd.copy();
for (int slot = 0; slot < this.itemHandler.getSlots(); slot++) {
ItemStack is = this.itemHandler.getStackInSlot(slot);
// First try filling slots
for (int slot = 0; slot < this.itemHandler.getSlotCount(); slot++) {
ItemStack is = this.itemHandler.getInvStack(slot);
if (Platform.itemComparisons().isSameItem(is, left)) {
left = this.itemHandler.insertItem(slot, left, simulate);
left = itemHandler.getSlot(slot).attemptInsertion(left, sim);
}
if (left.isEmpty()) {
return ItemStack.EMPTY;
}
}
for (int slot = 0; slot < this.itemHandler.getSlots(); slot++) {
left = this.itemHandler.insertItem(slot, left, simulate);
if (left.isEmpty()) {
return ItemStack.EMPTY;
}
}
return left;
return transferable.attemptInsertion(left, sim);
}
}
@@ -57,7 +57,7 @@ public class AdaptorList extends InventoryAdaptor {
if (amount > 0) {
final ItemStack rv = is.copy();
rv.setCount(amount);
is.grow(-amount);
is.increment(-amount);
// remove it..
if (is.getCount() <= 0) {
@@ -110,7 +110,7 @@ public class AdaptorList extends InventoryAdaptor {
if (amount > 0) {
final ItemStack rv = is.copy();
rv.setCount(amount);
is.grow(-amount);
is.increment(-amount);
// remove it..
if (is.getCount() <= 0) {
@@ -160,7 +160,7 @@ public class AdaptorList extends InventoryAdaptor {
for (final ItemStack is : this.i) {
if (ItemStack.areItemsEqual(is, left)) {
is.grow(left.getCount());
is.increment(left.getCount());
return ItemStack.EMPTY;
}
}
@@ -18,11 +18,11 @@
package appeng.util.inv;
import alexiil.mc.lib.attributes.item.ItemTransferable;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import net.minecraft.item.ItemStack;
public interface IAEAppEngInventory {
void saveChanges();
void onChangeInventory(ItemTransferable inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack);
void onChangeInventory(FixedItemInv inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack);
}
@@ -21,32 +21,33 @@ package appeng.util.inv;
import java.util.Iterator;
import java.util.NoSuchElementException;
import alexiil.mc.lib.attributes.item.ItemTransferable;
import alexiil.mc.lib.attributes.Simulation;
import alexiil.mc.lib.attributes.item.FixedItemInv;
class ItemHandlerIterator implements Iterator<ItemSlot> {
private final ItemTransferable itemHandler;
private final FixedItemInv itemHandler;
private final ItemSlot itemSlot = new ItemSlot();
private int slot = 0;
ItemHandlerIterator(ItemTransferable itemHandler) {
ItemHandlerIterator(FixedItemInv itemHandler) {
this.itemHandler = itemHandler;
}
@Override
public boolean hasNext() {
return this.slot < this.itemHandler.getSlots();
return this.slot < this.itemHandler.getSlotCount();
}
@Override
public ItemSlot next() {
if (this.slot >= this.itemHandler.getSlots()) {
if (this.slot >= this.itemHandler.getSlotCount()) {
throw new NoSuchElementException();
}
this.itemSlot.setExtractable(!this.itemHandler.extractItem(this.slot, 1, true).isEmpty());
this.itemSlot.setItemStack(this.itemHandler.getStackInSlot(this.slot));
this.itemSlot.setExtractable(!this.itemHandler.getSlot(this.slot).attemptAnyExtraction(1, Simulation.SIMULATE).isEmpty());
this.itemSlot.setItemStack(this.itemHandler.getInvStack(this.slot));
this.itemSlot.setSlot(this.slot);
this.slot++;
return this.itemSlot;
@@ -18,129 +18,17 @@
package appeng.util.inv;
import java.util.ArrayList;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import alexiil.mc.lib.attributes.item.impl.CombinedFixedItemInv;
import alexiil.mc.lib.attributes.item.impl.DelegatingFixedItemInv;
import javax.annotation.Nonnull;
import java.util.Arrays;
import alexiil.mc.lib.attributes.item.ItemTransferable;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandlerModifiable;
import alexiil.mc.lib.attributes.item.impl.EmptyFixedItemInv;
// FIXME could be replaced by CombinedFixedItemInv directly
public class WrapperChainedItemHandler extends DelegatingFixedItemInv {
import appeng.util.helpers.ItemHandlerUtil;
public class WrapperChainedItemHandler implements IItemHandlerModifiable {
private ItemTransferable[] itemHandler; // the handlers
private int[] baseIndex; // index-offsets of the different handlers
private int slotCount; // number of total slots
public WrapperChainedItemHandler(ItemTransferable... itemHandler) {
this.setItemHandlers(itemHandler);
public WrapperChainedItemHandler(FixedItemInv... itemHandler) {
super(CombinedFixedItemInv.create(Arrays.asList(itemHandler)));
}
private void setItemHandlers(ItemTransferable[] handlers) {
this.itemHandler = handlers;
this.baseIndex = new int[this.itemHandler.length];
int index = 0;
for (int i = 0; i < this.itemHandler.length; i++) {
index += this.itemHandler[i].getSlots();
this.baseIndex[i] = index;
}
this.slotCount = index;
}
// returns the handler index for the slot
private int getIndexForSlot(int slot) {
if (slot < 0) {
return -1;
}
for (int i = 0; i < this.baseIndex.length; i++) {
if (slot - this.baseIndex[i] < 0) {
return i;
}
}
return -1;
}
private ItemTransferable getHandlerFromIndex(int index) {
if (index < 0 || index >= this.itemHandler.length) {
return EmptyFixedItemInv.INSTANCE;
}
return this.itemHandler[index];
}
private int getSlotFromIndex(int slot, int index) {
if (index <= 0 || index >= this.baseIndex.length) {
return slot;
}
return slot - this.baseIndex[index - 1];
}
public void cycleOrder() {
if (this.itemHandler.length > 1) {
ArrayList<ItemTransferable> newOrder = new ArrayList<>();
newOrder.add(this.itemHandler[this.itemHandler.length - 1]);
for (int i = 0; i < this.itemHandler.length - 1; ++i) {
newOrder.add(this.itemHandler[i]);
}
this.setItemHandlers(newOrder.toArray(new ItemTransferable[this.itemHandler.length]));
}
}
@Override
public int getSlots() {
return this.slotCount;
}
@Override
@Nonnull
public ItemStack getStackInSlot(final int slot) {
int index = this.getIndexForSlot(slot);
ItemTransferable handler = this.getHandlerFromIndex(index);
int targetSlot = this.getSlotFromIndex(slot, index);
return handler.getStackInSlot(targetSlot);
}
@Override
@Nonnull
public ItemStack insertItem(final int slot, @Nonnull ItemStack stack, boolean simulate) {
int index = this.getIndexForSlot(slot);
ItemTransferable handler = this.getHandlerFromIndex(index);
int targetSlot = this.getSlotFromIndex(slot, index);
return handler.insertItem(targetSlot, stack, simulate);
}
@Override
@Nonnull
public ItemStack extractItem(int slot, int amount, boolean simulate) {
int index = this.getIndexForSlot(slot);
ItemTransferable handler = this.getHandlerFromIndex(index);
int targetSlot = this.getSlotFromIndex(slot, index);
return handler.extractItem(targetSlot, amount, simulate);
}
@Override
public int getSlotLimit(int slot) {
int index = this.getIndexForSlot(slot);
ItemTransferable handler = this.getHandlerFromIndex(index);
int localSlot = this.getSlotFromIndex(slot, index);
return handler.getSlotLimit(localSlot);
}
@Override
public void setStackInSlot(int slot, ItemStack stack) {
int index = this.getIndexForSlot(slot);
ItemTransferable handler = this.getHandlerFromIndex(index);
int targetSlot = this.getSlotFromIndex(slot, index);
ItemHandlerUtil.setStackInSlot(handler, targetSlot, stack);
}
@Override
public boolean isItemValid(int slot, ItemStack stack) {
int index = this.getIndexForSlot(slot);
ItemTransferable handler = this.getHandlerFromIndex(index);
int targetSlot = this.getSlotFromIndex(slot, index);
return handler.isItemValid(targetSlot, stack);
}
}
@@ -18,21 +18,14 @@
package appeng.util.inv;
import alexiil.mc.lib.attributes.item.compat.FixedInventoryVanillaWrapper;
import alexiil.mc.lib.attributes.item.impl.DelegatingFixedItemInv;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraftforge.items.ItemStackHandler;
public class WrapperCursorItemHandler extends ItemStackHandler {
private final PlayerInventory inv;
public class WrapperCursorItemHandler extends DelegatingFixedItemInv {
public WrapperCursorItemHandler(PlayerInventory PlayerInventory) {
super(1);
this.inv = PlayerInventory;
this.setStackInSlot(0, PlayerInventory.getItemStack());
public WrapperCursorItemHandler(PlayerInventory inventory) {
super(new FixedInventoryVanillaWrapper(inventory).getSubInv(0, 1));
}
@Override
protected void onContentsChanged(int slot) {
this.inv.setItemStack(this.getStackInSlot(slot));
}
}
@@ -19,66 +19,62 @@
package appeng.util.inv;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import alexiil.mc.lib.attributes.ListenerRemovalToken;
import alexiil.mc.lib.attributes.ListenerToken;
import alexiil.mc.lib.attributes.Simulation;
import alexiil.mc.lib.attributes.item.InvMarkDirtyListener;
import alexiil.mc.lib.attributes.item.filter.ItemFilter;
import net.minecraft.item.ItemStack;
import alexiil.mc.lib.attributes.item.ItemTransferable;
import net.minecraftforge.items.IItemHandlerModifiable;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import appeng.util.helpers.ItemHandlerUtil;
import appeng.util.inv.filter.IAEItemFilter;
public class WrapperFilteredItemHandler implements IItemHandlerModifiable {
private final ItemTransferable handler;
// FIXME: Needs to be double checked, LBA has better ways of doing this
public class WrapperFilteredItemHandler implements FixedItemInv {
private final FixedItemInv handler;
private final IAEItemFilter filter;
public WrapperFilteredItemHandler(@Nonnull ItemTransferable handler, @Nonnull IAEItemFilter filter) {
public WrapperFilteredItemHandler(@Nonnull FixedItemInv handler, @Nonnull IAEItemFilter filter) {
this.handler = handler;
this.filter = filter;
}
@Override
public void setStackInSlot(int slot, ItemStack stack) {
ItemHandlerUtil.setStackInSlot(this.handler, slot, stack);
public ItemStack getInvStack(int slot) {
return this.handler.getInvStack(slot);
}
@Override
public int getSlots() {
return this.handler.getSlots();
public boolean setInvStack(int slot, ItemStack to, Simulation simulation) {
return this.handler.setInvStack(slot, to, simulation);
}
@Override
public ItemStack getStackInSlot(int slot) {
return this.handler.getStackInSlot(slot);
public int getSlotCount() {
return this.handler.getSlotCount();
}
@Override
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
if (!this.filter.allowInsert(this.handler, slot, stack)) {
return stack;
}
return this.handler.insertItem(slot, stack, simulate);
public boolean isItemValidForSlot(int slot, ItemStack stack) {
return filter.allowInsert(handler, slot, stack);
}
@Override
public ItemStack extractItem(int slot, int amount, boolean simulate) {
if (!this.filter.allowExtract(this.handler, slot, amount)) {
return ItemStack.EMPTY;
}
return this.handler.extractItem(slot, amount, simulate);
public ItemFilter getFilterForSlot(int slot) {
return stack -> filter.allowInsert(handler, slot, stack);
}
@Override
public int getSlotLimit(int slot) {
return this.handler.getSlotLimit(slot);
public int getChangeValue() {
return this.handler.getChangeValue();
}
@Nullable
@Override
public boolean isItemValid(int slot, ItemStack stack) {
if (!this.filter.allowInsert(this.handler, slot, stack)) {
return false;
}
return this.handler.isItemValid(slot, stack);
public ListenerToken addListener(InvMarkDirtyListener listener, ListenerRemovalToken removalToken) {
return this.handler.addListener(listener, removalToken);
}
}
@@ -18,87 +18,19 @@
package appeng.util.inv;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import alexiil.mc.lib.attributes.item.compat.InventoryFixedWrapper;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import alexiil.mc.lib.attributes.item.ItemTransferable;
import appeng.util.helpers.ItemHandlerUtil;
public class WrapperInvItemHandler extends InventoryFixedWrapper {
public class WrapperInvItemHandler implements IInventory {
private final ItemTransferable inv;
public WrapperInvItemHandler(final ItemTransferable inv) {
this.inv = inv;
public WrapperInvItemHandler(final FixedItemInv inv) {
super(inv);
}
@Override
public int getSizeInventory() {
return this.inv.getSlots();
}
@Override
public boolean isEmpty() {
return ItemHandlerUtil.isEmpty(this.inv);
}
@Override
public ItemStack getStackInSlot(int index) {
return this.inv.getStackInSlot(index);
}
@Override
public ItemStack decrStackSize(int index, int count) {
return this.inv.extractItem(index, count, false);
}
@Override
public ItemStack removeStackFromSlot(int index) {
return this.inv.extractItem(index, this.inv.getSlotLimit(index), false);
}
@Override
public void setInventorySlotContents(int index, ItemStack stack) {
ItemHandlerUtil.setStackInSlot(this.inv, index, stack);
}
@Override
public int getInventoryStackLimit() {
int max = 0;
for (int i = 0; i < this.inv.getSlots(); ++i) {
max = Math.max(max, this.inv.getSlotLimit(i));
}
return max;
}
@Override
public void markDirty() {
// NOP
}
@Override
public boolean isUsableByPlayer(PlayerEntity player) {
public boolean canPlayerUse(PlayerEntity player) {
return false;
}
@Override
public void openInventory(PlayerEntity player) {
// NOP
}
@Override
public void closeInventory(PlayerEntity player) {
// NOP
}
@Override
public boolean isItemValidForSlot(int index, ItemStack stack) {
return this.inv.isItemValid(index, stack);
}
@Override
public void clear() {
ItemHandlerUtil.clear(this.inv);
}
}
@@ -1,102 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2017, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 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, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 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 Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.util.inv;
import javax.annotation.Nonnull;
import alexiil.mc.lib.attributes.item.ItemTransferable;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandlerModifiable;
import appeng.util.helpers.ItemHandlerUtil;
public class WrapperRangeItemHandler implements IItemHandlerModifiable {
private final ItemTransferable compose;
private final int minSlot;
private final int maxSlot;
public WrapperRangeItemHandler(ItemTransferable compose, int minSlot, int maxSlotExclusive) {
this.compose = compose;
this.minSlot = minSlot;
this.maxSlot = maxSlotExclusive;
}
@Override
public int getSlots() {
return this.maxSlot - this.minSlot;
}
@Override
@Nonnull
public ItemStack getStackInSlot(int slot) {
if (this.checkSlot(slot)) {
return this.compose.getStackInSlot(slot + this.minSlot);
}
return ItemStack.EMPTY;
}
@Override
@Nonnull
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) {
if (this.checkSlot(slot)) {
return this.compose.insertItem(slot + this.minSlot, stack, simulate);
}
return stack;
}
@Override
@Nonnull
public ItemStack extractItem(int slot, int amount, boolean simulate) {
if (this.checkSlot(slot)) {
return this.compose.extractItem(slot + this.minSlot, amount, simulate);
}
return ItemStack.EMPTY;
}
@Override
public void setStackInSlot(int slot, @Nonnull ItemStack stack) {
if (this.checkSlot(slot)) {
ItemHandlerUtil.setStackInSlot(this.compose, slot + this.minSlot, stack);
}
}
@Override
public int getSlotLimit(int slot) {
if (this.checkSlot(slot)) {
return this.compose.getSlotLimit(slot + this.minSlot);
}
return 0;
}
private boolean checkSlot(int localSlot) {
return localSlot + this.minSlot < this.maxSlot;
}
@Override
public boolean isItemValid(int slot, ItemStack stack) {
if (this.checkSlot(slot)) {
return this.compose.isItemValid(slot + this.minSlot, stack);
}
return false;
}
}
@@ -20,51 +20,58 @@ package appeng.util.inv;
import java.util.function.Supplier;
import alexiil.mc.lib.attributes.ListenerRemovalToken;
import alexiil.mc.lib.attributes.ListenerToken;
import alexiil.mc.lib.attributes.Simulation;
import alexiil.mc.lib.attributes.item.GroupedItemInv;
import alexiil.mc.lib.attributes.item.InvMarkDirtyListener;
import alexiil.mc.lib.attributes.item.impl.DelegatingGroupedItemInv;
import net.minecraft.item.ItemStack;
import alexiil.mc.lib.attributes.item.ItemTransferable;
import net.minecraftforge.items.IItemHandlerModifiable;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import appeng.util.helpers.ItemHandlerUtil;
import javax.annotation.Nullable;
public class WrapperSupplierItemHandler implements IItemHandlerModifiable {
private final Supplier<ItemTransferable> sourceHandler;
public class WrapperSupplierItemHandler implements FixedItemInv {
private final Supplier<FixedItemInv> sourceHandler;
public WrapperSupplierItemHandler(Supplier<ItemTransferable> source) {
public WrapperSupplierItemHandler(Supplier<FixedItemInv> source) {
this.sourceHandler = source;
}
@Override
public int getSlots() {
return this.sourceHandler.get().getSlots();
public GroupedItemInv getGroupedInv() {
return new DelegatingGroupedItemInv(this.sourceHandler.get().getGroupedInv());
}
@Override
public ItemStack getStackInSlot(int slot) {
return this.sourceHandler.get().getStackInSlot(slot);
public ItemStack getInvStack(int slot) {
return this.sourceHandler.get().getInvStack(slot);
}
@Override
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
return this.sourceHandler.get().insertItem(slot, stack, simulate);
public boolean setInvStack(int slot, ItemStack to, Simulation simulation) {
return this.sourceHandler.get().setInvStack(slot, to, simulation);
}
@Override
public ItemStack extractItem(int slot, int amount, boolean simulate) {
return this.sourceHandler.get().extractItem(slot, amount, simulate);
public int getSlotCount() {
return this.sourceHandler.get().getSlotCount();
}
@Override
public int getSlotLimit(int slot) {
return this.sourceHandler.get().getSlotLimit(slot);
public boolean isItemValidForSlot(int slot, ItemStack stack) {
return this.sourceHandler.get().isItemValidForSlot(slot, stack);
}
@Override
public void setStackInSlot(int slot, ItemStack stack) {
ItemHandlerUtil.setStackInSlot(this.sourceHandler.get(), slot, stack);
public int getChangeValue() {
return this.sourceHandler.get().getChangeValue();
}
@Nullable
@Override
public boolean isItemValid(int slot, ItemStack stack) {
return this.sourceHandler.get().isItemValid(slot, stack);
public ListenerToken addListener(InvMarkDirtyListener listener, ListenerRemovalToken removalToken) {
return this.sourceHandler.get().addListener(listener, removalToken);
}
}
@@ -18,7 +18,7 @@
package appeng.util.inv.filter;
import alexiil.mc.lib.attributes.item.ItemTransferable;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import net.minecraft.item.ItemStack;
import appeng.api.definitions.IItemDefinition;
@@ -31,12 +31,12 @@ public class AEItemDefinitionFilter implements IAEItemFilter {
}
@Override
public boolean allowExtract(ItemTransferable inv, int slot, int amount) {
public boolean allowExtract(FixedItemInv inv, int slot, int amount) {
return true;
}
@Override
public boolean allowInsert(ItemTransferable inv, int slot, ItemStack stack) {
public boolean allowInsert(FixedItemInv inv, int slot, ItemStack stack) {
return this.definition.isSameAs(stack);
}
@@ -18,7 +18,7 @@
package appeng.util.inv.filter;
import alexiil.mc.lib.attributes.item.ItemTransferable;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import net.minecraft.item.ItemStack;
public class AEItemFilters {
@@ -30,24 +30,24 @@ public class AEItemFilters {
private static class InsertOnlyFilter implements IAEItemFilter {
@Override
public boolean allowExtract(ItemTransferable inv, int slot, int amount) {
public boolean allowExtract(FixedItemInv inv, int slot, int amount) {
return false;
}
@Override
public boolean allowInsert(ItemTransferable inv, int slot, ItemStack stack) {
public boolean allowInsert(FixedItemInv inv, int slot, ItemStack stack) {
return true;
}
}
private static class ExtractOnlyFilter implements IAEItemFilter {
@Override
public boolean allowExtract(ItemTransferable inv, int slot, int amount) {
public boolean allowExtract(FixedItemInv inv, int slot, int amount) {
return true;
}
@Override
public boolean allowInsert(ItemTransferable inv, int slot, ItemStack stack) {
public boolean allowInsert(FixedItemInv inv, int slot, ItemStack stack) {
return false;
}
}
@@ -18,11 +18,11 @@
package appeng.util.inv.filter;
import alexiil.mc.lib.attributes.item.ItemTransferable;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import net.minecraft.item.ItemStack;
public interface IAEItemFilter {
boolean allowExtract(ItemTransferable inv, int slot, int amount);
boolean allowExtract(FixedItemInv inv, int slot, int amount);
boolean allowInsert(ItemTransferable inv, int slot, ItemStack stack);
boolean allowInsert(FixedItemInv inv, int slot, ItemStack stack);
}
@@ -31,7 +31,6 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.text.Text;
import net.fabricmc.api.EnvType;
import net.minecraftforge.items.ItemHandlerHelper;
import appeng.api.AEApi;
import appeng.api.config.FuzzyMode;
@@ -39,6 +38,7 @@ import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.util.Platform;
import net.minecraft.util.registry.Registry;
public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemStack {
private static final String NBT_STACKSIZE = "cnt";
@@ -81,7 +81,7 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
return null;
}
final ItemStack itemstack = ItemStack.read(i.getCompound(NBT_ITEMSTACK));
final ItemStack itemstack = ItemStack.fromTag(i.getCompound(NBT_ITEMSTACK));
if (itemstack.isEmpty()) {
return null;
}
@@ -96,7 +96,7 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
@Override
public void writeToNBT(final CompoundTag i) {
final CompoundTag itemStack = new CompoundTag();
this.getDefinition().write(itemStack);
this.getDefinition().toTag(itemStack);
i.put(NBT_ITEMSTACK, itemStack);
i.putLong(NBT_STACKSIZE, this.getStackSize());
@@ -169,7 +169,7 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
@Override
public ItemStack createItemStack() {
return ItemHandlerHelper.copyStackWithSize(this.getDefinition(),
return Platform.copyStackWithSize(this.getDefinition(),
(int) Math.min(Integer.MAX_VALUE, this.getStackSize()));
}
@@ -200,7 +200,7 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
int oldSize = otherStack.getCount();
otherStack.setCount(1);
boolean ret = ItemStack.areItemStacksEqual(this.getDefinition(), otherStack);
boolean ret = ItemStack.areEqual(this.getDefinition(), otherStack);
otherStack.setCount(oldSize);
return ret;
@@ -223,7 +223,7 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
@Override
public String toString() {
return this.getStackSize() + "x" + this.getDefinition().getItem().getRegistryName();
return this.getStackSize() + "x" + Registry.ITEM.getId(this.getDefinition().getItem());
}
@Environment(EnvType.CLIENT)
@@ -244,7 +244,7 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
@Environment(EnvType.CLIENT)
public String getModID() {
return this.getDefinition().getItem().getRegistryName().getNamespace();
return Registry.ITEM.getId(this.getDefinition().getItem()).getNamespace();
}
@Override
@@ -36,7 +36,7 @@ final class AESharedItemStack implements Comparable<AESharedItemStack> {
public AESharedItemStack(final ItemStack itemStack) {
this.itemStack = itemStack;
this.itemId = Item.getIdFromItem(itemStack.getItem());
this.itemId = Item.getRawId(itemStack.getItem());
this.itemDamage = itemStack.getDamage();
this.hashCode = this.makeHashCode();
}
@@ -73,7 +73,7 @@ final class AESharedItemStack implements Comparable<AESharedItemStack> {
if (this.itemStack == other.itemStack) {
return true;
}
return ItemStack.areItemStacksEqual(this.itemStack, other.itemStack);
return ItemStack.areEqual(this.itemStack, other.itemStack);
}
return false;
}
@@ -20,18 +20,18 @@ package appeng.util.iterators;
import java.util.Iterator;
import alexiil.mc.lib.attributes.item.ItemTransferable;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import net.minecraft.item.ItemStack;
public final class InvIterator implements Iterator<ItemStack> {
private final ItemTransferable inventory;
private final FixedItemInv inventory;
private final int size;
private int counter = 0;
public InvIterator(final ItemTransferable inventory) {
public InvIterator(final FixedItemInv inventory) {
this.inventory = inventory;
this.size = this.inventory.getSlots();
this.size = this.inventory.getSlotCount();
}
@Override
@@ -41,7 +41,7 @@ public final class InvIterator implements Iterator<ItemStack> {
@Override
public ItemStack next() {
final ItemStack result = this.inventory.getStackInSlot(this.counter);
final ItemStack result = this.inventory.getInvStack(this.counter);
this.counter++;
return result;