package WayofTime.bloodmagic.util; import WayofTime.bloodmagic.BloodMagic; import WayofTime.bloodmagic.api.BlockStack; import WayofTime.bloodmagic.api.Constants; import WayofTime.bloodmagic.api.altar.EnumAltarComponent; import WayofTime.bloodmagic.api.iface.IDemonWillViewer; import WayofTime.bloodmagic.api.util.helper.NBTHelper; import WayofTime.bloodmagic.core.RegistrarBloodMagicBlocks; import WayofTime.bloodmagic.network.BloodMagicPacketHandler; import WayofTime.bloodmagic.network.PlayerVelocityPacketProcessor; import WayofTime.bloodmagic.tile.TileInventory; import com.google.common.collect.Iterables; import net.minecraft.block.Block; import net.minecraft.block.BlockLiquid; import net.minecraft.block.BlockPortal; import net.minecraft.block.state.IBlockState; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; import net.minecraft.init.MobEffects; import net.minecraft.init.SoundEvents; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.Item; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.DamageSource; import net.minecraft.util.EnumFacing; import net.minecraft.util.SoundCategory; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraftforge.common.IPlantable; import net.minecraftforge.common.ISpecialArmor; import net.minecraftforge.common.ISpecialArmor.ArmorProperties; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fluids.IFluidBlock; import net.minecraftforge.fml.common.discovery.ASMDataTable; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.wrapper.InvWrapper; import net.minecraftforge.items.wrapper.PlayerMainInvWrapper; import net.minecraftforge.items.wrapper.SidedInvWrapper; import javax.annotation.Nullable; import java.util.*; public class Utils { public static float addAbsorptionToMaximum(EntityLivingBase entity, float added, int maximum, int duration) { float currentAmount = entity.getAbsorptionAmount(); added = Math.min(maximum - currentAmount, added); if (added <= 0) { return 0; } if (duration > 0) { int potionLevel = (int) ((currentAmount + added) / 4); entity.addPotionEffect(new PotionEffect(MobEffects.ABSORPTION, duration, potionLevel, true, false)); } entity.setAbsorptionAmount(currentAmount + added); return added; } public static boolean isImmuneToFireDamage(EntityLivingBase entity) { return entity.isImmuneToFire() || entity.isPotionActive(MobEffects.FIRE_RESISTANCE); } public static boolean isPlayerBesideSolidBlockFace(EntityPlayer player) { World world = player.getEntityWorld(); double minimumDistanceFromAxis = 0.7; BlockPos centralPos = player.getPosition(); for (EnumFacing facing : EnumFacing.HORIZONTALS) { BlockPos offsetPos = centralPos.offset(facing); double distance = Math.min(offsetPos.getX() + 0.5 - player.posX, offsetPos.getZ() + 0.5 - player.posZ); if (distance > minimumDistanceFromAxis) { continue; } IBlockState state = world.getBlockState(offsetPos); if (state.isSideSolid(world, offsetPos, facing.getOpposite())) { return true; } } return false; } public static boolean canPlayerSeeDemonWill(EntityPlayer player) { IItemHandler inventory = new PlayerMainInvWrapper(player.inventory); for (int i = 0; i < inventory.getSlots(); i++) { ItemStack stack = inventory.getStackInSlot(i); if (stack.isEmpty()) { continue; } if (stack.getItem() instanceof IDemonWillViewer && ((IDemonWillViewer) stack.getItem()).canSeeDemonWillAura(player.getEntityWorld(), stack, player)) { return true; } } return false; } public static boolean canEntitySeeBlock(World world, Entity entity, BlockPos pos) { Vec3d relativePosition = new Vec3d(entity.posX - pos.getX() - 0.5, entity.posY + (double) entity.getEyeHeight() - pos.getY() - 0.5, entity.posZ - pos.getZ() - 0.5); EnumFacing dir = EnumFacing.getFacingFromVector((float) relativePosition.x, (float) relativePosition.y, (float) relativePosition.z); RayTraceResult result = world.rayTraceBlocks(new Vec3d(entity.posX, entity.posY + (double) entity.getEyeHeight(), entity.posZ), new Vec3d(pos.getX() + 0.5 + dir.getFrontOffsetX() * 0.4, pos.getY() + 0.5 + dir.getFrontOffsetY() * 0.4, pos.getZ() + 0.5 + dir.getFrontOffsetZ() * 0.4), false, true, true); return result == null || pos.equals(result.getBlockPos()); } public static int plantSeedsInArea(World world, AxisAlignedBB aabb, int horizontalRadius, int verticalRadius) { int placedBlocks = 0; List itemEntities = world.getEntitiesWithinAABB(EntityItem.class, aabb); for (EntityItem itemEntity : itemEntities) { placedBlocks += plantEntityItem(itemEntity, horizontalRadius, verticalRadius); } return placedBlocks; } public static int plantItemStack(World world, BlockPos centralPos, ItemStack stack, int horizontalRadius, int verticalRadius) { if (stack.isEmpty()) { return 0; } Item item = stack.getItem(); if (!(item instanceof IPlantable)) { return 0; } int planted = 0; for (int hR = 0; hR <= horizontalRadius; hR++) { for (int vR = 0; vR <= verticalRadius; vR++) { for (int i = -hR; i <= hR; i++) { for (int k = -hR; k <= hR; k++) { for (int j = -vR; j <= vR; j += 2 * vR + (vR > 0 ? 0 : 1)) { if (!(Math.abs(i) == hR || Math.abs(k) == hR)) { continue; } BlockPos newPos = centralPos.add(i, j, k); if (world.isAirBlock(newPos)) { BlockPos offsetPos = newPos.offset(EnumFacing.DOWN); IBlockState state = world.getBlockState(offsetPos); if (state.getBlock().canSustainPlant(state, world, offsetPos, EnumFacing.UP, (IPlantable) item)) { IBlockState plantState = ((IPlantable) item).getPlant(world, newPos); world.setBlockState(newPos, plantState, 3); world.playEvent(2001, newPos, Block.getIdFromBlock(plantState.getBlock()) + (plantState.getBlock().getMetaFromState(plantState) << 12)); stack.shrink(1); planted++; if (stack.isEmpty() || stack.getCount() <= 0) { return planted; } } } } } } } } return planted; } public static int plantEntityItem(EntityItem itemEntity, int horizontalRadius, int verticalRadius) { if (itemEntity == null || itemEntity.isDead) { return 0; } World world = itemEntity.getEntityWorld(); BlockPos pos = itemEntity.getPosition(); ItemStack stack = itemEntity.getItem(); int planted = plantItemStack(world, pos, stack, horizontalRadius, verticalRadius); if (stack.isEmpty()) { itemEntity.setDead(); } return planted; } public static int getDemonWillResolution(EntityPlayer player) { IItemHandler inventory = new PlayerMainInvWrapper(player.inventory); for (int i = 0; i < inventory.getSlots(); i++) { ItemStack stack = inventory.getStackInSlot(i); if (stack.isEmpty()) { continue; } if (stack.getItem() instanceof IDemonWillViewer && ((IDemonWillViewer) stack.getItem()).canSeeDemonWillAura(player.getEntityWorld(), stack, player)) { return ((IDemonWillViewer) stack.getItem()).getDemonWillAuraResolution(player.getEntityWorld(), stack, player); } } return 1; } public static NBTTagCompound getPersistentDataTag(EntityPlayer player) { NBTTagCompound forgeData = player.getEntityData().getCompoundTag(EntityPlayer.PERSISTED_NBT_TAG); NBTTagCompound beaconData = forgeData.getCompoundTag("BloodMagic"); //Creates/sets the tags if they don't exist if (!forgeData.hasKey("BloodMagic")) forgeData.setTag("BloodMagic", beaconData); if (!player.getEntityData().hasKey(EntityPlayer.PERSISTED_NBT_TAG)) player.getEntityData().setTag(EntityPlayer.PERSISTED_NBT_TAG, forgeData); return beaconData; } public static void setPlayerSpeedFromServer(EntityPlayer player, double motionX, double motionY, double motionZ) { if (!player.getEntityWorld().isRemote && player instanceof EntityPlayerMP) { BloodMagicPacketHandler.sendTo(new PlayerVelocityPacketProcessor(motionX, motionY, motionZ), (EntityPlayerMP) player); } } public static boolean isInteger(String integer) { try { Integer.parseInt(integer); } catch (NumberFormatException e) { return false; } catch (NullPointerException e) { return false; } // only got here if we didn't return false return true; } public static String toFancyCasing(String input) { return String.valueOf(input.charAt(0)).toUpperCase(Locale.ENGLISH) + input.substring(1); } public static String prettifyBlockPosString(BlockPos pos) { return "[" + pos.getX() + ", " + pos.getY() + ", " + pos.getZ() + "]"; } /** * @param tile - The {@link TileInventory} to input the item to * @param player - The player to take the item from. * @return {@code true} if the ItemStack is inserted, {@code false} * otherwise * @see #insertItemToTile(TileInventory, EntityPlayer, int) */ public static boolean insertItemToTile(TileInventory tile, EntityPlayer player) { return insertItemToTile(tile, player, 0); } /** * Used for inserting an ItemStack with a stacksize of 1 to a tile's * inventory at slot 0 *

* EG: Block Altar * * @param tile - The {@link TileInventory} to input the item to * @param player - The player to take the item from. * @param slot - The slot to attempt to insert to * @return {@code true} if the ItemStack is inserted, {@code false} * otherwise */ public static boolean insertItemToTile(TileInventory tile, EntityPlayer player, int slot) { if (tile.getStackInSlot(slot).isEmpty() && !player.getHeldItemMainhand().isEmpty()) { ItemStack input = player.getHeldItemMainhand().copy(); input.setCount(1); player.getHeldItemMainhand().shrink(1); tile.setInventorySlotContents(slot, input); return true; } else if (!tile.getStackInSlot(slot).isEmpty() && player.getHeldItemMainhand().isEmpty()) { if (!tile.getWorld().isRemote) { EntityItem invItem = new EntityItem(tile.getWorld(), player.posX, player.posY + 0.25, player.posZ, tile.getStackInSlot(slot)); tile.getWorld().spawnEntity(invItem); } tile.clear(); return false; } return false; } public static double calculateStandardProgress(Number currentValue, int[] requiredValues, int currentLevel) { int nextLevel = currentLevel + 1; if (nextLevel >= requiredValues.length) return 1.0D; int required = requiredValues[nextLevel]; return Double.parseDouble("" + currentValue) / (double) required; } @Nullable public static IItemHandler getInventory(TileEntity tile, @Nullable EnumFacing facing) { if (facing == null) facing = EnumFacing.DOWN; IItemHandler itemHandler = null; if (tile.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, facing)) itemHandler = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, facing); else if (tile instanceof ISidedInventory) itemHandler = ((ISidedInventory) tile).getSlotsForFace(facing).length != 0 ? new SidedInvWrapper((ISidedInventory) tile, facing) : null; else if (tile instanceof IInventory) itemHandler = new InvWrapper((IInventory) tile); return itemHandler; } public static ItemStack setUnbreakable(ItemStack stack) { NBTHelper.checkNBT(stack); stack.getTagCompound().setBoolean("Unbreakable", true); return stack; } /** * Gets a default block for each type of {@link EnumAltarComponent} * * @param component - The Component to provide a block for. * @return The default Block for the EnumAltarComponent */ public static Block getBlockForComponent(EnumAltarComponent component) { switch (component) { case GLOWSTONE: return Blocks.GLOWSTONE; case BLOODSTONE: return RegistrarBloodMagicBlocks.DECORATIVE_BRICK; case BEACON: return Blocks.BEACON; case BLOODRUNE: return RegistrarBloodMagicBlocks.BLOOD_RUNE; case CRYSTAL: return RegistrarBloodMagicBlocks.BLOOD_RUNE; case NOTAIR: return Blocks.STONEBRICK; default: return Blocks.AIR; } } public static float getModifiedDamage(EntityLivingBase attackedEntity, DamageSource source, float amount) { if (!attackedEntity.isEntityInvulnerable(source)) { if (amount <= 0) return 0; amount = applyArmor(attackedEntity, Iterables.toArray(attackedEntity.getEquipmentAndArmor(), ItemStack.class), source, amount); if (amount <= 0) return 0; amount = applyPotionDamageCalculations(attackedEntity, source, amount); return amount; } return 0; } public static float applyArmor(EntityLivingBase entity, ItemStack[] inventory, DamageSource source, double damage) { damage *= 25; ArrayList dmgVals = new ArrayList(); for (int x = 0; x < inventory.length; x++) { ItemStack stack = inventory[x]; if (stack.isEmpty()) { continue; } ArmorProperties prop = null; if (stack.getItem() instanceof ISpecialArmor) { ISpecialArmor armor = (ISpecialArmor) stack.getItem(); prop = armor.getProperties(entity, stack, source, damage / 25D, x).copy(); } else if (stack.getItem() instanceof ItemArmor && !source.isUnblockable()) { ItemArmor armor = (ItemArmor) stack.getItem(); prop = new ArmorProperties(0, armor.damageReduceAmount / 25D, Integer.MAX_VALUE); } if (prop != null) { prop.Slot = x; dmgVals.add(prop); } } if (dmgVals.size() > 0) { ArmorProperties[] props = dmgVals.toArray(new ArmorProperties[dmgVals.size()]); int level = props[0].Priority; double ratio = 0; for (ArmorProperties prop : props) { if (level != prop.Priority) { damage -= (damage * ratio); ratio = 0; level = prop.Priority; } ratio += prop.AbsorbRatio; } damage -= (damage * ratio); } return (float) (damage / 25.0F); } public static float applyPotionDamageCalculations(EntityLivingBase attackedEntity, DamageSource source, float damage) { Potion resistance = MobEffects.RESISTANCE; if (source.isDamageAbsolute()) { return damage; } else { if (attackedEntity.isPotionActive(resistance) && source != DamageSource.OUT_OF_WORLD) { int i = (attackedEntity.getActivePotionEffect(resistance).getAmplifier() + 1) * 5; int j = 25 - i; float f = damage * (float) j; damage = f / 25.0F; } if (damage <= 0.0F) { return 0.0F; } else { int k = EnchantmentHelper.getEnchantmentModifierDamage(attackedEntity.getArmorInventoryList(), source); if (k > 20) { k = 20; } if (k > 0 && k <= 20) { int l = 25 - k; float f1 = damage * (float) l; damage = f1 / 25.0F; } return damage; } } } /** * Used to determine if stack1 can be placed into stack2. If stack2 is is empty * and stack1 isn't empty, returns true. Ignores stack size * * @param stack1 Stack that is placed into a slot * @param stack2 Slot content that stack1 is placed into * @return True if they can be combined * @deprecated use {@link ItemHandlerHelper#canItemStacksStack(ItemStack, ItemStack)} */ @Deprecated public static boolean canCombine(ItemStack stack1, ItemStack stack2) { return stack1.isEmpty() && !stack2.isEmpty() || ItemHandlerHelper.canItemStacksStack(stack1, stack2); } /** * @param stack1 Stack that is placed into a slot * @param stack2 Slot content that stack1 is placed into * @return Stacks after stacking */ public static ItemStack[] combineStacks(ItemStack stack1, ItemStack stack2, int transferMax) { ItemStack[] returned = new ItemStack[2]; if (ItemHandlerHelper.canItemStacksStack(stack1, stack2)) { int transferedAmount = Math.min(transferMax, stack2.isEmpty() ? stack1.getCount() : Math.min(stack2.getMaxStackSize() - stack2.getCount(), stack1.getCount())); if (transferedAmount > 0) { ItemStack copyStack = stack1.splitStack(transferedAmount); if (stack2.isEmpty()) { stack2 = copyStack; } else { stack2.grow(transferedAmount); } } } returned[0] = stack1; returned[1] = stack2; return returned; } /** * @param stack1 Stack that is placed into a slot * @param stack2 Slot content that stack1 is placed into * @return Stacks after stacking */ public static ItemStack[] combineStacks(ItemStack stack1, ItemStack stack2) { ItemStack[] returned = new ItemStack[2]; if (ItemHandlerHelper.canItemStacksStack(stack1, stack2)) { int transferedAmount = stack2.isEmpty() ? stack1.getCount() : Math.min(stack2.getMaxStackSize() - stack2.getCount(), stack1.getCount()); if (transferedAmount > 0) { ItemStack copyStack = stack1.splitStack(transferedAmount); if (stack2.isEmpty()) { stack2 = copyStack; } else { stack2.grow(transferedAmount); } } } returned[0] = stack1; returned[1] = stack2; return returned; } public static ItemStack insertStackIntoTile(ItemStack stack, TileEntity tile, EnumFacing dir) { if (tile.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, dir)) { IItemHandler handler = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, dir); return insertStackIntoTile(stack, handler); } else if (tile instanceof IInventory) { return insertStackIntoInventory(stack, (IInventory) tile, dir); } return stack; } public static int getNumberOfFreeSlots(TileEntity tile, EnumFacing dir) { int slots = 0; if (tile.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, dir)) { IItemHandler handler = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, dir); for (int i = 0; i < handler.getSlots(); i++) { if (handler.getStackInSlot(i).isEmpty()) { slots++; } } } else if (tile instanceof IInventory) { for (int i = 0; i < ((IInventory) tile).getSizeInventory(); i++) { if (((IInventory) tile).getStackInSlot(i).isEmpty()) { slots++; } } } return slots; } public static ItemStack insertStackIntoTile(ItemStack stack, IItemHandler handler) { int numberOfSlots = handler.getSlots(); ItemStack copyStack = stack.copy(); for (int slot = 0; slot < numberOfSlots; slot++) { copyStack = handler.insertItem(slot, copyStack, false); if (copyStack.isEmpty()) { return ItemStack.EMPTY; } } return copyStack; } /** * Inserts the desired stack into the tile up to a limit for the tile. * Respects capabilities. * * @param stack * @param tile * @param dir * @param limit * @return */ public static ItemStack insertStackIntoTile(ItemStack stack, TileEntity tile, EnumFacing dir, int limit) { if (tile.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, dir)) { IItemHandler handler = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, dir); int numberOfSlots = handler.getSlots(); ItemStack copyStack = stack.copy(); int numberMatching = 0; for (int slot = 0; slot < numberOfSlots; slot++) { ItemStack invStack = handler.getStackInSlot(slot); if (!invStack.isEmpty() && ItemHandlerHelper.canItemStacksStack(stack, invStack)) { numberMatching += invStack.getCount(); } } if (numberMatching >= limit) { return stack; } int newLimit = limit - numberMatching; for (int slot = 0; slot < numberOfSlots; slot++) { ItemStack newCopyStack = copyStack.copy(); newCopyStack.setCount(Math.min(copyStack.getCount(), newLimit)); newCopyStack = handler.insertItem(slot, newCopyStack, false); if (newCopyStack.isEmpty()) { return ItemStack.EMPTY; } newLimit -= (copyStack.getCount() - newCopyStack.getCount()); if (newLimit <= 0) { return ItemStack.EMPTY; //TODO } copyStack.shrink(copyStack.getCount() - newCopyStack.getCount()); } return copyStack; } else if (tile instanceof IInventory) { return insertStackIntoInventory(stack, (IInventory) tile, dir, limit); } return stack; } public static ItemStack insertStackIntoInventory(ItemStack stack, IInventory inventory, EnumFacing dir) { if (stack.isEmpty()) { return ItemStack.EMPTY; } boolean[] canBeInserted = new boolean[inventory.getSizeInventory()]; if (inventory instanceof ISidedInventory) { int[] array = ((ISidedInventory) inventory).getSlotsForFace(dir); for (int in : array) { canBeInserted[in] = inventory.isItemValidForSlot(in, stack) && ((ISidedInventory) inventory).canInsertItem(in, stack, dir); } } else { for (int i = 0; i < canBeInserted.length; i++) { canBeInserted[i] = inventory.isItemValidForSlot(i, stack); } } for (int i = 0; i < inventory.getSizeInventory(); i++) { if (!canBeInserted[i]) { continue; } ItemStack[] combinedStacks = combineStacks(stack, inventory.getStackInSlot(i)); stack = combinedStacks[0]; inventory.setInventorySlotContents(i, combinedStacks[1]); if (stack.isEmpty()) { return ItemStack.EMPTY; } } return stack; } public static boolean canInsertStackFullyIntoInventory(ItemStack stack, IInventory inventory, EnumFacing dir) { return canInsertStackFullyIntoInventory(stack, inventory, dir, false, 0); } public static boolean canInsertStackFullyIntoInventory(ItemStack stack, IInventory inventory, EnumFacing dir, boolean fillToLimit, int limit) { if (stack.isEmpty()) { return true; } int itemsLeft = stack.getCount(); boolean[] canBeInserted = new boolean[inventory.getSizeInventory()]; if (inventory instanceof ISidedInventory) { int[] array = ((ISidedInventory) inventory).getSlotsForFace(dir); for (int in : array) { canBeInserted[in] = inventory.isItemValidForSlot(in, stack) && ((ISidedInventory) inventory).canInsertItem(in, stack, dir); } } else { for (int i = 0; i < canBeInserted.length; i++) { canBeInserted[i] = inventory.isItemValidForSlot(i, stack); } } int numberMatching = 0; if (fillToLimit) { for (int i = 0; i < inventory.getSizeInventory(); i++) { if (!canBeInserted[i]) { continue; } ItemStack invStack = inventory.getStackInSlot(i); if (!invStack.isEmpty() && ItemHandlerHelper.canItemStacksStack(stack, invStack)) { numberMatching += invStack.getCount(); } } } if (fillToLimit && limit < stack.getCount() + numberMatching) { return false; } for (int i = 0; i < inventory.getSizeInventory(); i++) { if (!canBeInserted[i]) { continue; } ItemStack invStack = inventory.getStackInSlot(i); boolean canCombine = canCombine(stack, invStack); if (canCombine) { if (invStack.isEmpty()) { itemsLeft = 0; } else { itemsLeft -= (invStack.getMaxStackSize() - invStack.getCount()); } } if (itemsLeft <= 0) { return true; } } return false; } /** * Inserts the desired stack into the inventory up to a limit for the * inventory. * * @param stack * @param inventory * @param dir * @param limit * @return */ public static ItemStack insertStackIntoInventory(ItemStack stack, IInventory inventory, EnumFacing dir, int limit) { if (stack.isEmpty()) { return ItemStack.EMPTY; } boolean[] canBeInserted = new boolean[inventory.getSizeInventory()]; if (inventory instanceof ISidedInventory) { int[] array = ((ISidedInventory) inventory).getSlotsForFace(dir); for (int in : array) { canBeInserted[in] = ((ISidedInventory) inventory).canInsertItem(in, stack, dir); } } else { for (int i = 0; i < canBeInserted.length; i++) { canBeInserted[i] = true; } } int numberMatching = 0; for (int i = 0; i < inventory.getSizeInventory(); i++) { if (!canBeInserted[i]) { continue; } ItemStack invStack = inventory.getStackInSlot(i); if (!invStack.isEmpty() && canCombine(stack, invStack)) { numberMatching += invStack.getCount(); } } if (numberMatching >= limit) { return stack; } int newLimit = limit - numberMatching; for (int i = 0; i < inventory.getSizeInventory(); i++) { if (!canBeInserted[i]) { continue; } int prevStackSize = stack.getCount(); ItemStack[] combinedStacks = combineStacks(stack, inventory.getStackInSlot(i), newLimit); stack = combinedStacks[0]; inventory.setInventorySlotContents(i, combinedStacks[1]); //TODO newLimit -= (prevStackSize - stack.getCount()); if (newLimit <= 0 || stack.isEmpty()) { return stack; } } return stack; } public static boolean isBlockLiquid(IBlockState state) { return (state instanceof IFluidBlock || state.getMaterial().isLiquid()); } public static boolean isFlowingLiquid(World world, BlockPos pos, IBlockState state) { Block block = state.getBlock(); return ((block instanceof IFluidBlock && Math.abs(((IFluidBlock) block).getFilledPercentage(world, pos)) == 1) || (block instanceof BlockLiquid && block.getMetaFromState(state) != 0)); } public static boolean spawnStackAtBlock(World world, BlockPos pos, @Nullable EnumFacing pushDirection, ItemStack stack) { EntityItem entityItem = new EntityItem(world); BlockPos spawnPos = new BlockPos(pos); double velocity = 0.15D; if (pushDirection != null) { spawnPos.offset(pushDirection); switch (pushDirection) { case DOWN: { entityItem.motionY = -velocity; entityItem.setPosition(spawnPos.getX() + 0.5D, spawnPos.getY() - 1.0D, spawnPos.getZ() + 0.5D); break; } case UP: { entityItem.motionY = velocity; entityItem.setPosition(spawnPos.getX() + 0.5D, spawnPos.getY() + 1.0D, spawnPos.getZ() + 0.5D); break; } case NORTH: { entityItem.motionZ = -velocity; entityItem.setPosition(spawnPos.getX() + 0.5D, spawnPos.getY() + 0.5D, spawnPos.getZ() - 1.0D); break; } case SOUTH: { entityItem.motionZ = velocity; entityItem.setPosition(spawnPos.getX() + 0.5D, spawnPos.getY() + 0.5D, spawnPos.getZ() + 1.0D); break; } case WEST: { entityItem.motionX = -velocity; entityItem.setPosition(spawnPos.getX() - 1.0D, spawnPos.getY() + 0.5D, spawnPos.getZ() + 0.5D); break; } case EAST: { entityItem.motionX = velocity; entityItem.setPosition(spawnPos.getX() + 1.0D, spawnPos.getY() + 0.5D, spawnPos.getZ() + 0.5D); break; } } } entityItem.setItem(stack); return world.spawnEntity(entityItem); } public static boolean swapLocations(World initialWorld, BlockPos initialPos, World finalWorld, BlockPos finalPos) { return swapLocations(initialWorld, initialPos, finalWorld, finalPos, true); } public static boolean swapLocations(World initialWorld, BlockPos initialPos, World finalWorld, BlockPos finalPos, boolean playSound) { TileEntity initialTile = initialWorld.getTileEntity(initialPos); TileEntity finalTile = finalWorld.getTileEntity(finalPos); NBTTagCompound initialTag = new NBTTagCompound(); NBTTagCompound finalTag = new NBTTagCompound(); if (initialTile != null) initialTile.writeToNBT(initialTag); if (finalTile != null) finalTile.writeToNBT(finalTag); BlockStack initialStack = BlockStack.getStackFromPos(initialWorld, initialPos); BlockStack finalStack = BlockStack.getStackFromPos(finalWorld, finalPos); if ((initialStack.getBlock().equals(Blocks.AIR) && finalStack.getBlock().equals(Blocks.AIR)) || initialStack.getBlock() instanceof BlockPortal || finalStack.getBlock() instanceof BlockPortal) return false; if (playSound) { initialWorld.playSound(initialPos.getX(), initialPos.getY(), initialPos.getZ(), SoundEvents.ENTITY_ENDERMEN_TELEPORT, SoundCategory.AMBIENT, 1.0F, 1.0F, false); finalWorld.playSound(finalPos.getX(), finalPos.getY(), finalPos.getZ(), SoundEvents.ENTITY_ENDERMEN_TELEPORT, SoundCategory.AMBIENT, 1.0F, 1.0F, false); } //Finally, we get to do something! (CLEARING TILES) if (finalStack.getBlock() != null) finalWorld.removeTileEntity(finalPos); if (initialStack.getBlock() != null) initialWorld.removeTileEntity(initialPos); //TILES CLEARED IBlockState initialBlockState = initialWorld.getBlockState(initialPos); IBlockState finalBlockState = finalWorld.getBlockState(finalPos); finalWorld.setBlockState(finalPos, initialBlockState, 3); if (initialTile != null) { TileEntity newTileInitial = TileEntity.create(finalWorld, initialTag); finalWorld.setTileEntity(finalPos, newTileInitial); newTileInitial.setPos(finalPos); newTileInitial.setWorld(finalWorld); } initialWorld.setBlockState(initialPos, finalBlockState, 3); if (finalTile != null) { TileEntity newTileFinal = TileEntity.create(initialWorld, finalTag); initialWorld.setTileEntity(initialPos, newTileFinal); newTileFinal.setPos(initialPos); newTileFinal.setWorld(initialWorld); } initialWorld.notifyNeighborsOfStateChange(initialPos, finalStack.getBlock(), true); finalWorld.notifyNeighborsOfStateChange(finalPos, initialStack.getBlock(), true); return true; } //Shamelessly ripped off of CoFH Lib public static ItemStack consumeItem(ItemStack stack) { Item item = stack.getItem(); boolean largerStack = stack.getCount() > 1; if (largerStack) { stack.shrink(1); } if (item.hasContainerItem(stack)) { ItemStack ret = item.getContainerItem(stack); if (ret.isEmpty()) { return ItemStack.EMPTY; } if (ret.isItemStackDamageable() && ret.getItemDamage() > ret.getMaxDamage()) { ret = ItemStack.EMPTY; } return ret; } return largerStack ? stack : ItemStack.EMPTY; } public static void registerHandlers(Set eventHandlers) { for (ASMDataTable.ASMData data : eventHandlers) { try { Class handlerClass = Class.forName(data.getClassName()); Object handlerImpl = handlerClass.newInstance(); MinecraftForge.EVENT_BUS.register(handlerImpl); BloodMagic.LOGGER.debug("Registering event handler for class {}", data.getClassName()); } catch (Exception e) { // No-op } } } public static boolean hasUUID(ItemStack stack) { return stack.hasTagCompound() && stack.getTagCompound().hasKey(Constants.NBT.MOST_SIG) && stack.getTagCompound().hasKey(Constants.NBT.LEAST_SIG); } public static UUID getUUID(ItemStack stack) { if (!hasUUID(stack)) { return null; } return new UUID(stack.getTagCompound().getLong(Constants.NBT.MOST_SIG), stack.getTagCompound().getLong(Constants.NBT.LEAST_SIG)); } public static void setUUID(ItemStack stack) { stack = NBTHelper.checkNBT(stack); if (!stack.getTagCompound().hasKey(Constants.NBT.MOST_SIG) && !stack.getTagCompound().hasKey(Constants.NBT.LEAST_SIG)) { UUID itemUUID = UUID.randomUUID(); stack.getTagCompound().setLong(Constants.NBT.MOST_SIG, itemUUID.getMostSignificantBits()); stack.getTagCompound().setLong(Constants.NBT.LEAST_SIG, itemUUID.getLeastSignificantBits()); } } }