BloodMagic/src/main/java/WayofTime/bloodmagic/tile/TileAlchemyTable.java

372 lines
12 KiB
Java
Raw Normal View History

package WayofTime.bloodmagic.tile;
import WayofTime.bloodmagic.apibutnotreally.Constants;
import WayofTime.bloodmagic.apibutnotreally.orb.BloodOrb;
import WayofTime.bloodmagic.apibutnotreally.orb.IBloodOrb;
import WayofTime.bloodmagic.apibutnotreally.recipe.AlchemyTableRecipe;
import WayofTime.bloodmagic.apibutnotreally.registry.AlchemyTableRecipeRegistry;
import WayofTime.bloodmagic.apibutnotreally.saving.SoulNetwork;
import WayofTime.bloodmagic.apibutnotreally.util.helper.NetworkHelper;
2017-08-15 21:30:48 -07:00
import com.google.common.base.Strings;
2016-05-02 11:24:22 -04:00
import net.minecraft.block.state.IBlockState;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
2016-05-02 11:24:22 -04:00
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.BlockPos;
2016-05-02 11:24:22 -04:00
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
2016-05-02 11:24:22 -04:00
import net.minecraftforge.items.wrapper.SidedInvWrapper;
2017-08-15 21:30:48 -07:00
import java.util.ArrayList;
import java.util.List;
2017-08-15 21:30:48 -07:00
public class TileAlchemyTable extends TileInventory implements ISidedInventory, ITickable {
public static final int orbSlot = 6;
public static final int toolSlot = 7;
public static final int outputSlot = 8;
public EnumFacing direction = EnumFacing.NORTH;
public boolean isSlave = false;
2016-05-02 11:24:22 -04:00
public int burnTime = 0;
public int ticksRequired = 1;
public BlockPos connectedPos = BlockPos.ORIGIN;
2017-08-15 21:30:48 -07:00
public boolean[] blockedSlots = new boolean[]{false, false, false, false, false, false};
2017-08-15 21:30:48 -07:00
public TileAlchemyTable() {
super(9, "alchemyTable");
}
2017-08-15 21:30:48 -07:00
public void setInitialTableParameters(EnumFacing direction, boolean isSlave, BlockPos connectedPos) {
this.isSlave = isSlave;
this.connectedPos = connectedPos;
2017-08-15 21:30:48 -07:00
if (!isSlave) {
this.direction = direction;
}
}
2017-08-15 21:30:48 -07:00
public boolean isInvisible() {
return isSlave();
}
public boolean isInputSlotAccessible(int slot) {
return !(slot < 6 && slot >= 0) || !blockedSlots[slot];
}
2017-08-15 21:30:48 -07:00
public void toggleInputSlotAccessible(int slot) {
if (slot < 6 && slot >= 0)
blockedSlots[slot] = !blockedSlots[slot];
}
@Override
2017-08-15 21:30:48 -07:00
public void deserialize(NBTTagCompound tag) {
super.deserialize(tag);
isSlave = tag.getBoolean("isSlave");
direction = EnumFacing.getFront(tag.getInteger(Constants.NBT.DIRECTION));
connectedPos = new BlockPos(tag.getInteger(Constants.NBT.X_COORD), tag.getInteger(Constants.NBT.Y_COORD), tag.getInteger(Constants.NBT.Z_COORD));
2016-05-02 11:24:22 -04:00
burnTime = tag.getInteger("burnTime");
ticksRequired = tag.getInteger("ticksRequired");
byte[] array = tag.getByteArray("blockedSlots");
for (int i = 0; i < array.length; i++)
blockedSlots[i] = array[i] != 0;
}
@Override
2017-08-15 21:30:48 -07:00
public NBTTagCompound serialize(NBTTagCompound tag) {
super.serialize(tag);
tag.setBoolean("isSlave", isSlave);
tag.setInteger(Constants.NBT.DIRECTION, direction.getIndex());
tag.setInteger(Constants.NBT.X_COORD, connectedPos.getX());
tag.setInteger(Constants.NBT.Y_COORD, connectedPos.getY());
tag.setInteger(Constants.NBT.Z_COORD, connectedPos.getZ());
2016-05-02 11:24:22 -04:00
tag.setInteger("burnTime", burnTime);
tag.setInteger("ticksRequired", ticksRequired);
byte[] blockedSlotArray = new byte[blockedSlots.length];
for (int i = 0; i < blockedSlots.length; i++)
blockedSlotArray[i] = (byte) (blockedSlots[i] ? 1 : 0);
tag.setByteArray("blockedSlots", blockedSlotArray);
return tag;
2016-05-02 11:24:22 -04:00
}
@SuppressWarnings("unchecked")
@Override
2017-08-15 21:30:48 -07:00
public <T> T getCapability(Capability<T> capability, EnumFacing facing) {
if (facing != null && capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
if (this.isSlave()) {
2016-12-12 19:56:36 -08:00
TileEntity tile = getWorld().getTileEntity(connectedPos);
2017-08-15 21:30:48 -07:00
if (tile instanceof TileAlchemyTable) {
2016-05-02 11:24:22 -04:00
return (T) new SidedInvWrapper((TileAlchemyTable) tile, facing);
}
2017-08-15 21:30:48 -07:00
} else {
2016-05-02 11:24:22 -04:00
return (T) new SidedInvWrapper(this, facing);
}
}
return super.getCapability(capability, facing);
}
@Override
2017-08-15 21:30:48 -07:00
public int[] getSlotsForFace(EnumFacing side) {
switch (side) {
case DOWN:
return new int[]{outputSlot};
case UP:
return new int[]{orbSlot, toolSlot};
default:
return new int[]{0, 1, 2, 3, 4, 5};
}
}
@Override
2017-08-15 21:30:48 -07:00
public boolean canInsertItem(int index, ItemStack stack, EnumFacing direction) {
switch (direction) {
case DOWN:
return index != outputSlot && index != orbSlot && index != toolSlot;
case UP:
if (index == orbSlot && !stack.isEmpty() && stack.getItem() instanceof IBloodOrb) {
return true;
} else if (index == toolSlot) {
return false; //TODO:
} else {
return true;
}
default:
return getAccessibleInputSlots(direction).contains(index);
2016-05-02 11:24:22 -04:00
}
}
@Override
2017-08-15 21:30:48 -07:00
public boolean canExtractItem(int index, ItemStack stack, EnumFacing direction) {
switch (direction) {
case DOWN:
return index == outputSlot;
case UP:
if (index == orbSlot && !stack.isEmpty() && stack.getItem() instanceof IBloodOrb) {
return true;
} else if (index == toolSlot) {
return true; //TODO:
} else {
return true;
}
default:
return getAccessibleInputSlots(direction).contains(index);
2016-05-02 11:24:22 -04:00
}
}
2017-08-15 21:30:48 -07:00
public List<Integer> getAccessibleInputSlots(EnumFacing direction) {
List<Integer> list = new ArrayList<Integer>();
2017-08-15 21:30:48 -07:00
for (int i = 0; i < 6; i++) {
if (isInputSlotAccessible(i)) {
list.add(i);
}
}
return list;
}
@Override
2017-08-15 21:30:48 -07:00
public void update() {
if (isSlave()) {
2016-05-02 11:24:22 -04:00
return;
}
List<ItemStack> inputList = new ArrayList<ItemStack>();
2017-08-15 21:30:48 -07:00
for (int i = 0; i < 6; i++) {
if (!getStackInSlot(i).isEmpty()) {
2016-05-02 11:24:22 -04:00
inputList.add(getStackInSlot(i));
}
}
int tier = getTierOfOrb();
AlchemyTableRecipe recipe = AlchemyTableRecipeRegistry.getMatchingRecipe(inputList, getWorld(), getPos());
2017-08-15 21:30:48 -07:00
if (recipe != null && (burnTime > 0 || (!getWorld().isRemote && tier >= recipe.getTierRequired() && this.getContainedLp() >= recipe.getLpDrained()))) {
if (burnTime == 1) {
2016-12-12 19:56:36 -08:00
IBlockState state = getWorld().getBlockState(pos);
getWorld().notifyBlockUpdate(getPos(), state, state, 3);
2016-05-02 11:24:22 -04:00
}
2017-08-15 21:30:48 -07:00
if (canCraft(inputList, recipe)) {
2016-05-02 11:24:22 -04:00
ticksRequired = recipe.getTicksRequired();
burnTime++;
2017-08-15 21:30:48 -07:00
if (burnTime == ticksRequired) {
if (!getWorld().isRemote) {
2016-05-02 11:24:22 -04:00
int requiredLp = recipe.getLpDrained();
2017-08-15 21:30:48 -07:00
if (requiredLp > 0) {
if (!getWorld().isRemote) {
2016-05-02 11:24:22 -04:00
consumeLp(requiredLp);
}
}
2017-08-15 21:30:48 -07:00
if (!getWorld().isRemote) {
craftItem(inputList, recipe);
2016-05-02 11:24:22 -04:00
}
}
burnTime = 0;
2016-12-12 19:56:36 -08:00
IBlockState state = getWorld().getBlockState(pos);
getWorld().notifyBlockUpdate(getPos(), state, state, 3);
2017-08-15 21:30:48 -07:00
} else if (burnTime > ticksRequired + 10) {
2016-05-02 11:24:22 -04:00
burnTime = 0;
}
2017-08-15 21:30:48 -07:00
} else {
2016-05-02 11:24:22 -04:00
burnTime = 0;
}
2017-08-15 21:30:48 -07:00
} else {
2016-05-02 11:24:22 -04:00
burnTime = 0;
}
}
2017-08-15 21:30:48 -07:00
public double getProgressForGui() {
2016-05-02 11:24:22 -04:00
return ((double) burnTime) / ticksRequired;
}
2017-08-15 21:30:48 -07:00
private boolean canCraft(List<ItemStack> inputList, AlchemyTableRecipe recipe) {
if (recipe == null) {
2016-05-02 11:24:22 -04:00
return false;
}
ItemStack outputStack = recipe.getRecipeOutput(inputList);
2016-05-02 11:24:22 -04:00
ItemStack currentOutputStack = getStackInSlot(outputSlot);
2016-12-12 19:56:36 -08:00
if (outputStack.isEmpty())
2016-05-02 11:24:22 -04:00
return false;
2016-12-12 19:56:36 -08:00
if (currentOutputStack.isEmpty())
2016-05-02 11:24:22 -04:00
return true;
if (!ItemHandlerHelper.canItemStacksStack(outputStack, currentOutputStack))
2016-05-02 11:24:22 -04:00
return false;
2016-12-12 19:56:36 -08:00
int result = currentOutputStack.getCount() + outputStack.getCount();
2016-05-02 11:24:22 -04:00
return result <= getInventoryStackLimit() && result <= currentOutputStack.getMaxStackSize();
}
2017-08-15 21:30:48 -07:00
public int getTierOfOrb() {
2016-05-02 11:24:22 -04:00
ItemStack orbStack = getStackInSlot(orbSlot);
2017-08-15 21:30:48 -07:00
if (!orbStack.isEmpty()) {
if (orbStack.getItem() instanceof IBloodOrb) {
2017-08-15 20:21:54 -07:00
BloodOrb orb = ((IBloodOrb) orbStack.getItem()).getOrb(orbStack);
return orb == null ? 0 : orb.getTier();
2016-05-02 11:24:22 -04:00
}
}
return 0;
}
2017-08-15 21:30:48 -07:00
public int getContainedLp() {
2016-05-02 11:24:22 -04:00
ItemStack orbStack = getStackInSlot(orbSlot);
2017-08-15 21:30:48 -07:00
if (!orbStack.isEmpty()) {
if (orbStack.getItem() instanceof IBloodOrb) {
2016-05-02 11:24:22 -04:00
NBTTagCompound itemTag = orbStack.getTagCompound();
2017-08-15 21:30:48 -07:00
if (itemTag == null) {
2016-05-02 11:24:22 -04:00
return 0;
}
String ownerUUID = itemTag.getString(Constants.NBT.OWNER_UUID);
2017-08-15 21:30:48 -07:00
if (Strings.isNullOrEmpty(ownerUUID)) {
2016-05-02 11:24:22 -04:00
return 0;
}
SoulNetwork network = NetworkHelper.getSoulNetwork(ownerUUID);
return network.getCurrentEssence();
}
}
return 0;
}
2017-08-15 21:30:48 -07:00
public void craftItem(List<ItemStack> inputList, AlchemyTableRecipe recipe) {
if (this.canCraft(inputList, recipe)) {
ItemStack outputStack = recipe.getRecipeOutput(inputList);
2016-05-02 11:24:22 -04:00
ItemStack currentOutputStack = getStackInSlot(outputSlot);
2017-08-15 21:30:48 -07:00
if (currentOutputStack.isEmpty()) {
2016-05-02 11:24:22 -04:00
setInventorySlotContents(outputSlot, outputStack);
2017-08-15 21:30:48 -07:00
} else if (ItemHandlerHelper.canItemStacksStack(outputStack, currentOutputStack)) {
currentOutputStack.grow(outputStack.getCount());
2016-05-02 11:24:22 -04:00
}
consumeInventory(recipe);
2016-05-02 11:24:22 -04:00
}
}
2017-08-15 21:30:48 -07:00
public int consumeLp(int requested) {
2016-05-02 11:24:22 -04:00
ItemStack orbStack = getStackInSlot(orbSlot);
2017-08-15 21:30:48 -07:00
if (!orbStack.isEmpty()) {
if (orbStack.getItem() instanceof IBloodOrb) {
if (NetworkHelper.syphonFromContainer(orbStack, requested)) {
2016-05-02 11:24:22 -04:00
return requested;
}
}
}
return 0;
}
2017-08-15 21:30:48 -07:00
public void consumeInventory(AlchemyTableRecipe recipe) {
ItemStack[] input = new ItemStack[6];
2017-08-15 21:30:48 -07:00
for (int i = 0; i < 6; i++) {
input[i] = getStackInSlot(i);
}
2016-05-02 11:24:22 -04:00
ItemStack[] result = recipe.getRemainingItems(input);
2017-08-15 21:30:48 -07:00
for (int i = 0; i < 6; i++) {
setInventorySlotContents(i, result[i]);
2016-05-02 11:24:22 -04:00
}
}
public EnumFacing getDirection() {
return direction;
}
public boolean isSlave() {
return isSlave;
}
public int getBurnTime() {
return burnTime;
}
public int getTicksRequired() {
return ticksRequired;
}
public BlockPos getConnectedPos() {
return connectedPos;
}
public boolean[] getBlockedSlots() {
return blockedSlots;
}
2017-08-15 21:30:48 -07:00
public static int getOrbSlot() {
return orbSlot;
}
public static int getToolSlot() {
return toolSlot;
}
public static int getOutputSlot() {
return outputSlot;
}
}