BloodMagic/src/main/java/WayofTime/bloodmagic/util/Utils.java

960 lines
36 KiB
Java
Raw Normal View History

package WayofTime.bloodmagic.util;
2017-08-15 21:30:48 -07:00
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;
2016-01-09 18:17:38 -05:00
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;
2016-01-09 18:17:38 -05:00
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;
2016-12-12 19:56:36 -08:00
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.wrapper.InvWrapper;
2016-12-12 19:56:36 -08:00
import net.minecraftforge.items.wrapper.PlayerMainInvWrapper;
import net.minecraftforge.items.wrapper.SidedInvWrapper;
2017-08-15 21:30:48 -07:00
import javax.annotation.Nullable;
import java.util.*;
2017-08-15 21:30:48 -07:00
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);
2017-08-15 21:30:48 -07:00
if (added <= 0) {
return 0;
}
2017-08-15 21:30:48 -07:00
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;
}
2017-08-15 21:30:48 -07:00
public static boolean isImmuneToFireDamage(EntityLivingBase entity) {
return entity.isImmuneToFire() || entity.isPotionActive(MobEffects.FIRE_RESISTANCE);
}
2017-08-15 21:30:48 -07:00
public static boolean isPlayerBesideSolidBlockFace(EntityPlayer player) {
2016-12-12 19:56:36 -08:00
World world = player.getEntityWorld();
double minimumDistanceFromAxis = 0.7;
BlockPos centralPos = player.getPosition();
2017-08-15 21:30:48 -07:00
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);
2017-08-15 21:30:48 -07:00
if (distance > minimumDistanceFromAxis) {
continue;
}
IBlockState state = world.getBlockState(offsetPos);
2017-08-15 21:30:48 -07:00
if (state.isSideSolid(world, offsetPos, facing.getOpposite())) {
return true;
}
}
return false;
}
2017-08-15 21:30:48 -07:00
public static boolean canPlayerSeeDemonWill(EntityPlayer player) {
2016-12-12 19:56:36 -08:00
IItemHandler inventory = new PlayerMainInvWrapper(player.inventory);
2017-08-15 21:30:48 -07:00
for (int i = 0; i < inventory.getSlots(); i++) {
2016-12-12 19:56:36 -08:00
ItemStack stack = inventory.getStackInSlot(i);
2017-08-15 21:30:48 -07:00
if (stack.isEmpty()) {
continue;
}
2017-08-15 21:30:48 -07:00
if (stack.getItem() instanceof IDemonWillViewer && ((IDemonWillViewer) stack.getItem()).canSeeDemonWillAura(player.getEntityWorld(), stack, player)) {
return true;
}
}
return false;
}
2017-08-15 21:30:48 -07:00
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);
2016-12-12 19:56:36 -08:00
return result == null || pos.equals(result.getBlockPos());
}
2017-08-15 21:30:48 -07:00
public static int plantSeedsInArea(World world, AxisAlignedBB aabb, int horizontalRadius, int verticalRadius) {
int placedBlocks = 0;
List<EntityItem> itemEntities = world.getEntitiesWithinAABB(EntityItem.class, aabb);
2017-08-15 21:30:48 -07:00
for (EntityItem itemEntity : itemEntities) {
placedBlocks += plantEntityItem(itemEntity, horizontalRadius, verticalRadius);
}
return placedBlocks;
}
2017-08-15 21:30:48 -07:00
public static int plantItemStack(World world, BlockPos centralPos, ItemStack stack, int horizontalRadius, int verticalRadius) {
if (stack.isEmpty()) {
return 0;
}
Item item = stack.getItem();
2017-08-15 21:30:48 -07:00
if (!(item instanceof IPlantable)) {
return 0;
}
int planted = 0;
2017-08-15 21:30:48 -07:00
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);
2017-08-15 21:30:48 -07:00
if (world.isAirBlock(newPos)) {
BlockPos offsetPos = newPos.offset(EnumFacing.DOWN);
IBlockState state = world.getBlockState(offsetPos);
2017-08-15 21:30:48 -07:00
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));
2016-12-12 19:56:36 -08:00
stack.shrink(1);
planted++;
2017-08-15 21:30:48 -07:00
if (stack.isEmpty() || stack.getCount() <= 0) {
return planted;
}
}
}
}
}
}
}
}
return planted;
}
2017-08-15 21:30:48 -07:00
public static int plantEntityItem(EntityItem itemEntity, int horizontalRadius, int verticalRadius) {
if (itemEntity == null || itemEntity.isDead) {
return 0;
}
2016-12-12 19:56:36 -08:00
World world = itemEntity.getEntityWorld();
BlockPos pos = itemEntity.getPosition();
ItemStack stack = itemEntity.getItem();
int planted = plantItemStack(world, pos, stack, horizontalRadius, verticalRadius);
2017-08-15 21:30:48 -07:00
if (stack.isEmpty()) {
itemEntity.setDead();
}
return planted;
}
2017-08-15 21:30:48 -07:00
public static int getDemonWillResolution(EntityPlayer player) {
2016-12-12 19:56:36 -08:00
IItemHandler inventory = new PlayerMainInvWrapper(player.inventory);
2017-08-15 21:30:48 -07:00
for (int i = 0; i < inventory.getSlots(); i++) {
2016-12-12 19:56:36 -08:00
ItemStack stack = inventory.getStackInSlot(i);
2017-08-15 21:30:48 -07:00
if (stack.isEmpty()) {
continue;
}
2017-08-15 21:30:48 -07:00
if (stack.getItem() instanceof IDemonWillViewer && ((IDemonWillViewer) stack.getItem()).canSeeDemonWillAura(player.getEntityWorld(), stack, player)) {
2016-12-12 19:56:36 -08:00
return ((IDemonWillViewer) stack.getItem()).getDemonWillAuraResolution(player.getEntityWorld(), stack, player);
}
}
return 1;
}
2017-08-15 21:30:48 -07:00
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;
}
2017-08-15 21:30:48 -07:00
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);
}
}
2017-08-15 21:30:48 -07:00
public static boolean isInteger(String integer) {
try {
Integer.parseInt(integer);
2017-08-15 21:30:48 -07:00
} catch (NumberFormatException e) {
return false;
2017-08-15 21:30:48 -07:00
} catch (NullPointerException e) {
return false;
}
// only got here if we didn't return false
return true;
}
2017-08-15 21:30:48 -07:00
public static String toFancyCasing(String input) {
return String.valueOf(input.charAt(0)).toUpperCase(Locale.ENGLISH) + input.substring(1);
}
2017-08-15 21:30:48 -07:00
public static String prettifyBlockPosString(BlockPos pos) {
return "[" + pos.getX() + ", " + pos.getY() + ", " + pos.getZ() + "]";
}
/**
2017-08-15 21:30:48 -07:00
* @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}
2017-08-15 21:30:48 -07:00
* otherwise
* @see #insertItemToTile(TileInventory, EntityPlayer, int)
*/
2017-08-15 21:30:48 -07:00
public static boolean insertItemToTile(TileInventory tile, EntityPlayer player) {
return insertItemToTile(tile, player, 0);
}
2016-01-01 10:52:42 -08:00
/**
* Used for inserting an ItemStack with a stacksize of 1 to a tile's
* inventory at slot 0
* <p/>
2016-01-01 10:52:42 -08:00
* EG: Block Altar
2017-08-15 21:30:48 -07:00
*
* @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}
2017-08-15 21:30:48 -07:00
* otherwise
2016-01-01 10:52:42 -08:00
*/
2017-08-15 21:30:48 -07:00
public static boolean insertItemToTile(TileInventory tile, EntityPlayer player, int slot) {
if (tile.getStackInSlot(slot).isEmpty() && !player.getHeldItemMainhand().isEmpty()) {
ItemStack input = player.getHeldItemMainhand().copy();
2016-12-12 19:56:36 -08:00
input.setCount(1);
player.getHeldItemMainhand().shrink(1);
tile.setInventorySlotContents(slot, input);
2015-11-27 20:15:19 -05:00
return true;
2017-08-15 21:30:48 -07:00
} 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));
2016-12-12 19:56:36 -08:00
tile.getWorld().spawnEntity(invItem);
}
tile.clear();
2015-11-27 20:15:19 -05:00
return false;
}
2015-11-27 20:15:19 -05:00
return false;
}
2017-08-15 21:30:48 -07:00
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
2017-08-15 21:30:48 -07:00
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;
}
2017-08-15 21:30:48 -07:00
public static ItemStack setUnbreakable(ItemStack stack) {
NBTHelper.checkNBT(stack);
stack.getTagCompound().setBoolean("Unbreakable", true);
return stack;
}
2016-01-01 10:52:42 -08:00
/**
* Gets a default block for each type of {@link EnumAltarComponent}
2017-08-15 21:30:48 -07:00
*
* @param component - The Component to provide a block for.
2016-01-01 10:52:42 -08:00
* @return The default Block for the EnumAltarComponent
*/
2017-08-15 21:30:48 -07:00
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;
}
2017-08-15 21:30:48 -07:00
public static float applyArmor(EntityLivingBase entity, ItemStack[] inventory, DamageSource source, double damage) {
damage *= 25;
ArrayList<ArmorProperties> dmgVals = new ArrayList<ArmorProperties>();
2017-08-15 21:30:48 -07:00
for (int x = 0; x < inventory.length; x++) {
ItemStack stack = inventory[x];
2017-08-15 21:30:48 -07:00
if (stack.isEmpty()) {
continue;
}
ArmorProperties prop = null;
2017-08-15 21:30:48 -07:00
if (stack.getItem() instanceof ISpecialArmor) {
ISpecialArmor armor = (ISpecialArmor) stack.getItem();
prop = armor.getProperties(entity, stack, source, damage / 25D, x).copy();
2017-08-15 21:30:48 -07:00
} else if (stack.getItem() instanceof ItemArmor && !source.isUnblockable()) {
ItemArmor armor = (ItemArmor) stack.getItem();
prop = new ArmorProperties(0, armor.damageReduceAmount / 25D, Integer.MAX_VALUE);
}
2017-08-15 21:30:48 -07:00
if (prop != null) {
prop.Slot = x;
dmgVals.add(prop);
}
}
2017-08-15 21:30:48 -07:00
if (dmgVals.size() > 0) {
ArmorProperties[] props = dmgVals.toArray(new ArmorProperties[dmgVals.size()]);
int level = props[0].Priority;
double ratio = 0;
2017-08-15 21:30:48 -07:00
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);
}
2017-08-15 21:30:48 -07:00
public static float applyPotionDamageCalculations(EntityLivingBase attackedEntity, DamageSource source, float damage) {
2016-04-24 10:06:28 -07:00
Potion resistance = MobEffects.RESISTANCE;
2017-08-15 21:30:48 -07:00
if (source.isDamageAbsolute()) {
return damage;
2017-08-15 21:30:48 -07:00
} 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;
}
2017-08-15 21:30:48 -07:00
if (damage <= 0.0F) {
return 0.0F;
2017-08-15 21:30:48 -07:00
} else {
int k = EnchantmentHelper.getEnchantmentModifierDamage(attackedEntity.getArmorInventoryList(), source);
2017-08-15 21:30:48 -07:00
if (k > 20) {
k = 20;
}
2017-08-15 21:30:48 -07:00
if (k > 0 && k <= 20) {
int l = 25 - k;
float f1 = damage * (float) l;
damage = f1 / 25.0F;
}
return damage;
}
}
}
2016-01-09 18:17:38 -05:00
/**
* 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
2017-08-15 21:30:48 -07:00
*
* @param stack1 Stack that is placed into a slot
* @param stack2 Slot content that stack1 is placed into
2016-01-09 18:17:38 -05:00
* @return True if they can be combined
2016-12-12 19:56:36 -08:00
* @deprecated use {@link ItemHandlerHelper#canItemStacksStack(ItemStack, ItemStack)}
2016-01-09 18:17:38 -05:00
*/
2016-12-12 19:56:36 -08:00
@Deprecated
2017-08-15 21:30:48 -07:00
public static boolean canCombine(ItemStack stack1, ItemStack stack2) {
return stack1.isEmpty() && !stack2.isEmpty() || ItemHandlerHelper.canItemStacksStack(stack1, stack2);
2016-01-09 18:17:38 -05:00
}
/**
2017-08-15 21:30:48 -07:00
* @param stack1 Stack that is placed into a slot
* @param stack2 Slot content that stack1 is placed into
2016-01-09 18:17:38 -05:00
* @return Stacks after stacking
*/
2017-08-15 21:30:48 -07:00
public static ItemStack[] combineStacks(ItemStack stack1, ItemStack stack2, int transferMax) {
2016-01-09 18:17:38 -05:00
ItemStack[] returned = new ItemStack[2];
2017-08-15 21:30:48 -07:00
if (ItemHandlerHelper.canItemStacksStack(stack1, stack2)) {
2016-12-12 19:56:36 -08:00
int transferedAmount = Math.min(transferMax, stack2.isEmpty() ? stack1.getCount() : Math.min(stack2.getMaxStackSize() - stack2.getCount(), stack1.getCount()));
2017-08-15 21:30:48 -07:00
if (transferedAmount > 0) {
2016-01-09 18:17:38 -05:00
ItemStack copyStack = stack1.splitStack(transferedAmount);
2017-08-15 21:30:48 -07:00
if (stack2.isEmpty()) {
2016-01-09 18:17:38 -05:00
stack2 = copyStack;
2017-08-15 21:30:48 -07:00
} else {
2016-12-12 19:56:36 -08:00
stack2.grow(transferedAmount);
2016-01-09 18:17:38 -05:00
}
}
}
returned[0] = stack1;
returned[1] = stack2;
return returned;
}
/**
2017-08-15 21:30:48 -07:00
* @param stack1 Stack that is placed into a slot
* @param stack2 Slot content that stack1 is placed into
2016-01-09 18:17:38 -05:00
* @return Stacks after stacking
*/
2017-08-15 21:30:48 -07:00
public static ItemStack[] combineStacks(ItemStack stack1, ItemStack stack2) {
2016-01-09 18:17:38 -05:00
ItemStack[] returned = new ItemStack[2];
2017-08-15 21:30:48 -07:00
if (ItemHandlerHelper.canItemStacksStack(stack1, stack2)) {
2016-12-12 19:56:36 -08:00
int transferedAmount = stack2.isEmpty() ? stack1.getCount() : Math.min(stack2.getMaxStackSize() - stack2.getCount(), stack1.getCount());
2017-08-15 21:30:48 -07:00
if (transferedAmount > 0) {
2016-01-09 18:17:38 -05:00
ItemStack copyStack = stack1.splitStack(transferedAmount);
2017-08-15 21:30:48 -07:00
if (stack2.isEmpty()) {
2016-01-09 18:17:38 -05:00
stack2 = copyStack;
2017-08-15 21:30:48 -07:00
} else {
2016-12-12 19:56:36 -08:00
stack2.grow(transferedAmount);
2016-01-09 18:17:38 -05:00
}
}
}
returned[0] = stack1;
returned[1] = stack2;
return returned;
}
2017-08-15 21:30:48 -07:00
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);
2017-08-15 21:30:48 -07:00
} else if (tile instanceof IInventory) {
return insertStackIntoInventory(stack, (IInventory) tile, dir);
}
return stack;
}
2017-08-15 21:30:48 -07:00
public static int getNumberOfFreeSlots(TileEntity tile, EnumFacing dir) {
int slots = 0;
2017-08-15 21:30:48 -07:00
if (tile.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, dir)) {
IItemHandler handler = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, dir);
2017-08-15 21:30:48 -07:00
for (int i = 0; i < handler.getSlots(); i++) {
if (handler.getStackInSlot(i).isEmpty()) {
slots++;
}
}
2017-08-15 21:30:48 -07:00
} else if (tile instanceof IInventory) {
for (int i = 0; i < ((IInventory) tile).getSizeInventory(); i++) {
if (((IInventory) tile).getStackInSlot(i).isEmpty()) {
slots++;
}
}
}
return slots;
}
2017-08-15 21:30:48 -07:00
public static ItemStack insertStackIntoTile(ItemStack stack, IItemHandler handler) {
int numberOfSlots = handler.getSlots();
ItemStack copyStack = stack.copy();
2017-08-15 21:30:48 -07:00
for (int slot = 0; slot < numberOfSlots; slot++) {
copyStack = handler.insertItem(slot, copyStack, false);
2017-08-15 21:30:48 -07:00
if (copyStack.isEmpty()) {
2017-01-01 21:43:34 -08:00
return ItemStack.EMPTY;
}
}
return copyStack;
}
/**
* Inserts the desired stack into the tile up to a limit for the tile.
* Respects capabilities.
2017-08-15 21:30:48 -07:00
*
* @param stack
* @param tile
* @param dir
* @param limit
* @return
*/
2017-08-15 21:30:48 -07:00
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;
2017-08-15 21:30:48 -07:00
for (int slot = 0; slot < numberOfSlots; slot++) {
ItemStack invStack = handler.getStackInSlot(slot);
2017-08-15 21:30:48 -07:00
if (!invStack.isEmpty() && ItemHandlerHelper.canItemStacksStack(stack, invStack)) {
2016-12-12 19:56:36 -08:00
numberMatching += invStack.getCount();
}
}
2017-08-15 21:30:48 -07:00
if (numberMatching >= limit) {
return stack;
}
int newLimit = limit - numberMatching;
2017-08-15 21:30:48 -07:00
for (int slot = 0; slot < numberOfSlots; slot++) {
ItemStack newCopyStack = copyStack.copy();
2016-12-12 19:56:36 -08:00
newCopyStack.setCount(Math.min(copyStack.getCount(), newLimit));
newCopyStack = handler.insertItem(slot, newCopyStack, false);
2017-08-15 21:30:48 -07:00
if (newCopyStack.isEmpty()) {
2016-12-12 19:56:36 -08:00
return ItemStack.EMPTY;
}
2016-12-12 19:56:36 -08:00
newLimit -= (copyStack.getCount() - newCopyStack.getCount());
2017-08-15 21:30:48 -07:00
if (newLimit <= 0) {
2016-12-12 19:56:36 -08:00
return ItemStack.EMPTY; //TODO
}
2016-12-12 19:56:36 -08:00
copyStack.shrink(copyStack.getCount() - newCopyStack.getCount());
}
return copyStack;
2017-08-15 21:30:48 -07:00
} else if (tile instanceof IInventory) {
return insertStackIntoInventory(stack, (IInventory) tile, dir, limit);
}
return stack;
}
2017-08-15 21:30:48 -07:00
public static ItemStack insertStackIntoInventory(ItemStack stack, IInventory inventory, EnumFacing dir) {
if (stack.isEmpty()) {
2016-12-12 19:56:36 -08:00
return ItemStack.EMPTY;
2016-01-09 18:17:38 -05:00
}
boolean[] canBeInserted = new boolean[inventory.getSizeInventory()];
2017-08-15 21:30:48 -07:00
if (inventory instanceof ISidedInventory) {
2016-01-09 18:17:38 -05:00
int[] array = ((ISidedInventory) inventory).getSlotsForFace(dir);
2017-08-15 21:30:48 -07:00
for (int in : array) {
2016-01-09 18:17:38 -05:00
canBeInserted[in] = inventory.isItemValidForSlot(in, stack) && ((ISidedInventory) inventory).canInsertItem(in, stack, dir);
}
2017-08-15 21:30:48 -07:00
} else {
for (int i = 0; i < canBeInserted.length; i++) {
2016-01-09 18:17:38 -05:00
canBeInserted[i] = inventory.isItemValidForSlot(i, stack);
}
}
2017-08-15 21:30:48 -07:00
for (int i = 0; i < inventory.getSizeInventory(); i++) {
if (!canBeInserted[i]) {
2016-01-09 18:17:38 -05:00
continue;
}
ItemStack[] combinedStacks = combineStacks(stack, inventory.getStackInSlot(i));
stack = combinedStacks[0];
inventory.setInventorySlotContents(i, combinedStacks[1]);
2017-08-15 21:30:48 -07:00
if (stack.isEmpty()) {
2016-12-12 19:56:36 -08:00
return ItemStack.EMPTY;
2016-01-09 18:17:38 -05:00
}
}
return stack;
}
2017-08-15 21:30:48 -07:00
public static boolean canInsertStackFullyIntoInventory(ItemStack stack, IInventory inventory, EnumFacing dir) {
2016-01-09 18:17:38 -05:00
return canInsertStackFullyIntoInventory(stack, inventory, dir, false, 0);
}
2017-08-15 21:30:48 -07:00
public static boolean canInsertStackFullyIntoInventory(ItemStack stack, IInventory inventory, EnumFacing dir, boolean fillToLimit, int limit) {
if (stack.isEmpty()) {
2016-01-09 18:17:38 -05:00
return true;
}
2016-12-12 19:56:36 -08:00
int itemsLeft = stack.getCount();
2016-01-09 18:17:38 -05:00
boolean[] canBeInserted = new boolean[inventory.getSizeInventory()];
2017-08-15 21:30:48 -07:00
if (inventory instanceof ISidedInventory) {
2016-01-09 18:17:38 -05:00
int[] array = ((ISidedInventory) inventory).getSlotsForFace(dir);
2017-08-15 21:30:48 -07:00
for (int in : array) {
2016-01-09 18:17:38 -05:00
canBeInserted[in] = inventory.isItemValidForSlot(in, stack) && ((ISidedInventory) inventory).canInsertItem(in, stack, dir);
}
2017-08-15 21:30:48 -07:00
} else {
for (int i = 0; i < canBeInserted.length; i++) {
2016-01-09 18:17:38 -05:00
canBeInserted[i] = inventory.isItemValidForSlot(i, stack);
}
}
int numberMatching = 0;
2017-08-15 21:30:48 -07:00
if (fillToLimit) {
for (int i = 0; i < inventory.getSizeInventory(); i++) {
if (!canBeInserted[i]) {
2016-01-09 18:17:38 -05:00
continue;
}
ItemStack invStack = inventory.getStackInSlot(i);
2017-08-15 21:30:48 -07:00
if (!invStack.isEmpty() && ItemHandlerHelper.canItemStacksStack(stack, invStack)) {
2016-12-12 19:56:36 -08:00
numberMatching += invStack.getCount();
2016-01-09 18:17:38 -05:00
}
}
}
2017-08-15 21:30:48 -07:00
if (fillToLimit && limit < stack.getCount() + numberMatching) {
2016-01-09 18:17:38 -05:00
return false;
}
2017-08-15 21:30:48 -07:00
for (int i = 0; i < inventory.getSizeInventory(); i++) {
if (!canBeInserted[i]) {
2016-01-09 18:17:38 -05:00
continue;
}
ItemStack invStack = inventory.getStackInSlot(i);
boolean canCombine = canCombine(stack, invStack);
2017-08-15 21:30:48 -07:00
if (canCombine) {
if (invStack.isEmpty()) {
2016-01-09 18:17:38 -05:00
itemsLeft = 0;
2017-08-15 21:30:48 -07:00
} else {
2016-12-12 19:56:36 -08:00
itemsLeft -= (invStack.getMaxStackSize() - invStack.getCount());
2016-01-09 18:17:38 -05:00
}
}
2017-08-15 21:30:48 -07:00
if (itemsLeft <= 0) {
2016-01-09 18:17:38 -05:00
return true;
}
}
return false;
}
/**
* Inserts the desired stack into the inventory up to a limit for the
* inventory.
2017-08-15 21:30:48 -07:00
*
* @param stack
* @param inventory
* @param dir
* @param limit
* @return
*/
2017-08-15 21:30:48 -07:00
public static ItemStack insertStackIntoInventory(ItemStack stack, IInventory inventory, EnumFacing dir, int limit) {
if (stack.isEmpty()) {
2016-12-12 19:56:36 -08:00
return ItemStack.EMPTY;
2016-01-09 18:17:38 -05:00
}
boolean[] canBeInserted = new boolean[inventory.getSizeInventory()];
2017-08-15 21:30:48 -07:00
if (inventory instanceof ISidedInventory) {
2016-01-09 18:17:38 -05:00
int[] array = ((ISidedInventory) inventory).getSlotsForFace(dir);
2017-08-15 21:30:48 -07:00
for (int in : array) {
2016-01-09 18:17:38 -05:00
canBeInserted[in] = ((ISidedInventory) inventory).canInsertItem(in, stack, dir);
}
2017-08-15 21:30:48 -07:00
} else {
for (int i = 0; i < canBeInserted.length; i++) {
2016-01-09 18:17:38 -05:00
canBeInserted[i] = true;
}
}
int numberMatching = 0;
2017-08-15 21:30:48 -07:00
for (int i = 0; i < inventory.getSizeInventory(); i++) {
if (!canBeInserted[i]) {
2016-01-09 18:17:38 -05:00
continue;
}
ItemStack invStack = inventory.getStackInSlot(i);
2017-08-15 21:30:48 -07:00
if (!invStack.isEmpty() && canCombine(stack, invStack)) {
2016-12-12 19:56:36 -08:00
numberMatching += invStack.getCount();
2016-01-09 18:17:38 -05:00
}
}
2017-08-15 21:30:48 -07:00
if (numberMatching >= limit) {
2016-01-09 18:17:38 -05:00
return stack;
}
int newLimit = limit - numberMatching;
2017-08-15 21:30:48 -07:00
for (int i = 0; i < inventory.getSizeInventory(); i++) {
if (!canBeInserted[i]) {
2016-01-09 18:17:38 -05:00
continue;
}
2016-12-12 19:56:36 -08:00
int prevStackSize = stack.getCount();
2016-01-09 18:17:38 -05:00
ItemStack[] combinedStacks = combineStacks(stack, inventory.getStackInSlot(i), newLimit);
stack = combinedStacks[0];
inventory.setInventorySlotContents(i, combinedStacks[1]); //TODO
2016-01-09 18:17:38 -05:00
2016-12-12 19:56:36 -08:00
newLimit -= (prevStackSize - stack.getCount());
2016-01-09 18:17:38 -05:00
2017-08-15 21:30:48 -07:00
if (newLimit <= 0 || stack.isEmpty()) {
2016-01-09 18:17:38 -05:00
return stack;
}
}
return stack;
}
2017-08-15 21:30:48 -07:00
public static boolean isBlockLiquid(IBlockState state) {
return (state instanceof IFluidBlock || state.getMaterial().isLiquid());
}
2017-08-15 21:30:48 -07:00
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));
}
2017-08-15 21:30:48 -07:00
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;
2017-08-15 21:30:48 -07:00
if (pushDirection != null) {
spawnPos.offset(pushDirection);
2017-08-15 21:30:48 -07:00
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);
2016-12-12 19:56:36 -08:00
return world.spawnEntity(entityItem);
}
2017-08-15 21:30:48 -07:00
public static boolean swapLocations(World initialWorld, BlockPos initialPos, World finalWorld, BlockPos finalPos) {
return swapLocations(initialWorld, initialPos, finalWorld, finalPos, true);
}
2017-08-15 21:30:48 -07:00
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);
2016-04-24 10:06:28 -07:00
if ((initialStack.getBlock().equals(Blocks.AIR) && finalStack.getBlock().equals(Blocks.AIR)) || initialStack.getBlock() instanceof BlockPortal || finalStack.getBlock() instanceof BlockPortal)
return false;
2017-08-15 21:30:48 -07:00
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);
2017-08-15 21:30:48 -07:00
if (initialTile != null) {
2016-12-12 19:56:36 -08:00
TileEntity newTileInitial = TileEntity.create(finalWorld, initialTag);
finalWorld.setTileEntity(finalPos, newTileInitial);
newTileInitial.setPos(finalPos);
2016-12-12 19:56:36 -08:00
newTileInitial.setWorld(finalWorld);
}
initialWorld.setBlockState(initialPos, finalBlockState, 3);
2017-08-15 21:30:48 -07:00
if (finalTile != null) {
2016-12-12 19:56:36 -08:00
TileEntity newTileFinal = TileEntity.create(initialWorld, finalTag);
initialWorld.setTileEntity(initialPos, newTileFinal);
newTileFinal.setPos(initialPos);
2016-12-12 19:56:36 -08:00
newTileFinal.setWorld(initialWorld);
}
2016-12-12 19:56:36 -08:00
initialWorld.notifyNeighborsOfStateChange(initialPos, finalStack.getBlock(), true);
finalWorld.notifyNeighborsOfStateChange(finalPos, initialStack.getBlock(), true);
return true;
}
//Shamelessly ripped off of CoFH Lib
2017-08-15 21:30:48 -07:00
public static ItemStack consumeItem(ItemStack stack) {
Item item = stack.getItem();
2016-12-12 19:56:36 -08:00
boolean largerStack = stack.getCount() > 1;
2017-08-15 21:30:48 -07:00
if (largerStack) {
2016-12-12 19:56:36 -08:00
stack.shrink(1);
}
2017-08-15 21:30:48 -07:00
if (item.hasContainerItem(stack)) {
ItemStack ret = item.getContainerItem(stack);
2017-08-15 21:30:48 -07:00
if (ret.isEmpty()) {
2016-12-12 19:56:36 -08:00
return ItemStack.EMPTY;
}
2017-08-15 21:30:48 -07:00
if (ret.isItemStackDamageable() && ret.getItemDamage() > ret.getMaxDamage()) {
2016-12-12 19:56:36 -08:00
ret = ItemStack.EMPTY;
}
return ret;
}
2016-12-12 19:56:36 -08:00
return largerStack ? stack : ItemStack.EMPTY;
}
2017-08-15 21:30:48 -07:00
public static void registerHandlers(Set<ASMDataTable.ASMData> eventHandlers) {
for (ASMDataTable.ASMData data : eventHandlers) {
try {
Class<?> handlerClass = Class.forName(data.getClassName());
Object handlerImpl = handlerClass.newInstance();
MinecraftForge.EVENT_BUS.register(handlerImpl);
BloodMagic.instance.logger.debug("Registering event handler for class {}", data.getClassName());
2017-08-15 21:30:48 -07:00
} catch (Exception e) {
// No-op
}
}
}
2017-08-15 21:30:48 -07:00
public static boolean hasUUID(ItemStack stack) {
return stack.hasTagCompound() && stack.getTagCompound().hasKey(Constants.NBT.MOST_SIG) && stack.getTagCompound().hasKey(Constants.NBT.LEAST_SIG);
}
2017-08-15 21:30:48 -07:00
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));
}
2017-08-15 21:30:48 -07:00
public static void setUUID(ItemStack stack) {
stack = NBTHelper.checkNBT(stack);
2017-08-15 21:30:48 -07:00
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());
}
}
}