package sourcecoded.quantum.tile; import net.minecraft.block.Block; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import sourcecoded.core.util.RandomUtils; import sourcecoded.quantum.api.QuantumAPI; import sourcecoded.quantum.api.block.IRiftMultiplier; import sourcecoded.quantum.api.discovery.DiscoveryManager; import sourcecoded.quantum.api.energy.EnergyBehaviour; import sourcecoded.quantum.api.energy.ITileRiftHandler; import sourcecoded.quantum.api.energy.RiftEnergyStorage; import sourcecoded.quantum.api.event.crafting.InjectionCraftingEvent; import sourcecoded.quantum.api.injection.IInjectorRecipe; import sourcecoded.quantum.api.injection.InjectorRegistry; import sourcecoded.quantum.client.renderer.fx.helpers.FXManager; import sourcecoded.quantum.discovery.QADiscoveries; import sourcecoded.quantum.registry.QABlocks; import sourcecoded.quantum.registry.QAItems; import sourcecoded.quantum.structure.MultiblockLayer; import sourcecoded.quantum.util.WorldUtils; public class TileRiftInjector extends TileDyeable implements ITileRiftHandler, ISidedInventory { public RiftEnergyStorage rift; public ItemStack currentItem; public int ticker = 0; public int multiblockTicker = 0; public int tier; public float speed = 1F; public float energy = 1F; /* The amount of energy to infuse per tick */ public int energyPerTick = 100; public int energyInfused = 0; boolean isParticle = false; MultiblockLayer tier1 = new MultiblockLayer("cic", "i i", "cic", 'c', QABlocks.INJECTED_CORNERSTONE.getBlock(), 'i', QABlocks.INJECTED_STONE.getBlock()); MultiblockLayer tier2 = new MultiblockLayer("ciiic", "i i", "i i", "i i", "ciiic", 'c', QABlocks.INJECTED_CORNERSTONE.getBlock(), 'i', QABlocks.INJECTED_STONE.getBlock()); MultiblockLayer[] tier3 = { new MultiblockLayer("ciiiiic", "i i", "i i", "i i", "i i", "i i", "ciiiiic", 'c', QABlocks.INJECTED_CORNERSTONE.getBlock(), 'i', QABlocks.INJECTED_STONE.getBlock()), new MultiblockLayer("i i", " ", " ", " ", " ", " ", "i i", 'i', QABlocks.INJECTED_STONE.getBlock()), new MultiblockLayer("i i", " ", " ", " ", " ", " ", "i i", 'i', QABlocks.INJECTED_STONE.getBlock()), new MultiblockLayer("i i", " ", " ", " ", " ", " ", "i i", 'i', QABlocks.INJECTED_STONE.getBlock()), new MultiblockLayer("c c", " ", " ", " ", " ", " ", "c c", 'c', QABlocks.INJECTED_CORNERSTONE.getBlock()), }; public EntityPlayer recentPlayer; public TileRiftInjector() { rift = new RiftEnergyStorage(100000); } public void updateEntity() { if (ticker >= 10) { speed = WorldUtils.getMultiplication(worldObj, xCoord, yCoord, zCoord, 5, 5, 5, IRiftMultiplier.RiftMultiplierTypes.SPEED); energy = WorldUtils.getMultiplication(worldObj, xCoord, yCoord, zCoord, 5, 5, 5, IRiftMultiplier.RiftMultiplierTypes.ENERGY_USAGE); ticker = 0; } ticker++; if (!this.worldObj.isRemote) { if (this.currentItem != null) { if (this.canInject()) { int energyToTake = (int) Math.floor((float)energyPerTick / (float)speed); if (energyToTake < getRiftEnergy()) { isParticle = true; energyInfused += energyToTake; takeRiftEnergy(energyToTake); IInjectorRecipe recipe = InjectorRegistry.getRecipeForInput(currentItem); if (energyInfused >= (recipe.getEnergyRequired() * currentItem.stackSize)) { inject(); energyInfused = 0; update(); } } else { isParticle = false; update(); } } else energyInfused = 0; } else energyInfused = 0; if (multiblockTicker >= 100) multiblockTicker = 0; if (multiblockTicker == 0) tier = getTier(); if (energyInfused == 0) isParticle = false; } else { if (isParticle && ticker % 5 == 0) { FXManager.injectionFX(0.1F, worldObj, xCoord + 0.5F, yCoord + 0.3F, zCoord + 0.5F, true, getColour()); FXManager.injectionFX(0.1F, worldObj, xCoord + 0.5F, yCoord + 0.3F, zCoord + 0.5F, false, getColour()); } } multiblockTicker++; } public int getTier() { int tier = 0; if (tier1.valid(worldObj, xCoord, yCoord - 1, zCoord)) tier = 1; else return tier; if (tier2.valid(worldObj, xCoord, yCoord - 2, zCoord)) tier = 2; else return tier; for (int i = 0; i < tier3.length; i++) if (!tier3[i].valid(worldObj, xCoord, yCoord - 3 + i, zCoord)) return tier; tier++; return tier; } public void click(EntityPlayer clickEntity) { if (clickEntity.getCurrentEquippedItem() == null) { if (currentItem == null) return; worldObj.spawnEntityInWorld(new EntityItem(worldObj, xCoord, yCoord + 1D, zCoord, currentItem)); currentItem = null; update(); } else if (currentItem == null || currentItem.isItemEqual(clickEntity.getCurrentEquippedItem())) { ItemStack held = clickEntity.getCurrentEquippedItem(); ItemStack newHeld = held.copy(); if (InjectorRegistry.getRecipeForInput(held) == null) return; newHeld.stackSize = 1; if (currentItem != null && newHeld.isItemEqual(currentItem)) { if (currentItem.stackSize == getInventoryStackLimit()) return; currentItem.stackSize++; } if (currentItem == null) { currentItem = newHeld; } held.stackSize--; clickEntity.setCurrentItemOrArmor(0, held); update(); } recentPlayer = clickEntity; } void inject() { if (this.canInject()) { IInjectorRecipe recipe = InjectorRegistry.getRecipeForInput(currentItem); ItemStack itemstack = recipe.getOutput(); itemstack.stackSize *= currentItem.stackSize; currentItem = itemstack; QuantumAPI.eventBus.post(new InjectionCraftingEvent.Complete(recipe, this.worldObj, currentItem, this)); if (RandomUtils.nextInt(0, 2) == 0 && recentPlayer != null) { DiscoveryManager.unlockItem(QADiscoveries.Item.INJECTION_ADV.get().getKey(), recentPlayer, false); } if (recentPlayer != null) { //Do relevant discoveries if (Block.getBlockFromItem(currentItem.getItem()) == QABlocks.RIFT_SMELTER.getBlock()) DiscoveryManager.unlockItem(QADiscoveries.Item.FURNACE.get().getKey(), recentPlayer, false); if (currentItem.getItem() == QAItems.INJECTED_STRING.getItem()) DiscoveryManager.unlockItem(QADiscoveries.Item.STRING.get().getKey(), recentPlayer, false); if (currentItem.getItem() == QAItems.INJECTED_STICK.getItem() && currentItem.getItemDamage() == 0) DiscoveryManager.unlockItem(QADiscoveries.Item.STICK.get().getKey(), recentPlayer, false); if (currentItem.getItem() == QAItems.OBSIDIAN_JEWEL.getItem() && currentItem.getItemDamage() == 1) DiscoveryManager.unlockItem(QADiscoveries.Item.JEWEL_CHARGED.get().getKey(), recentPlayer, false); } } } boolean canInject() { if (!InjectorRegistry.hasRecipeForInput(currentItem)) return false; IInjectorRecipe recipe = InjectorRegistry.getRecipeForInput(currentItem); if (worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord)) return false; if (recipe.getTier() > tier) return false; if (this.currentItem == null) return false; else { ItemStack itemstack = recipe.getOutput(); if (itemstack == null) return false; int result = currentItem.stackSize * itemstack.stackSize; if (QuantumAPI.eventBus.post(new InjectionCraftingEvent.Validating(recipe, worldObj, currentItem, this))) return false; return result <= getInventoryStackLimit() && result <= this.currentItem.getMaxStackSize(); } } @Override public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); rift.writeRiftToNBT(nbt); nbt.setInteger("energyInfused", energyInfused); NBTTagList nbttaglist = new NBTTagList(); if (this.currentItem != null) { NBTTagCompound nbttagcompound1 = new NBTTagCompound(); this.currentItem.writeToNBT(nbttagcompound1); nbttaglist.appendTag(nbttagcompound1); } nbt.setTag("Items", nbttaglist); nbt.setBoolean("isCooking", isParticle); } @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); rift.readRiftFromNBT(nbt); energyInfused = nbt.getInteger("energyInfused"); NBTTagList nbttaglist = nbt.getTagList("Items", 10); NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(0); this.currentItem = ItemStack.loadItemStackFromNBT(nbttagcompound1); isParticle = nbt.getBoolean("isCooking"); } @Override public int takeRiftEnergy(int amount) { update(); return rift.takeRiftEnergy(amount); } @Override public int giveRiftEnergy(int amount) { update(); return rift.giveRiftEnergy(amount); } @Override public int getRiftEnergy() { return rift.getRiftEnergy(); } @Override public int getMaxRiftEnergy() { return rift.getMaxRiftEnergy(); } @Override public EnergyBehaviour getBehaviour() { return EnergyBehaviour.DRAIN; } @Override public int[] getAccessibleSlotsFromSide(int side) { return new int[]{0, 1, 2, 3, 4, 5}; } @Override public boolean canInsertItem(int slot, ItemStack item, int side) { update(); return this.isItemValidForSlot(slot, item); } @Override public boolean canExtractItem(int slot, ItemStack item, int side) { update(); return true; } @Override public int getSizeInventory() { return 1; } @Override public ItemStack getStackInSlot(int slot) { return currentItem; } @Override public ItemStack decrStackSize(int slot, int amount) { if (this.currentItem != null) { ItemStack itemstack; if (this.currentItem.stackSize <= amount) { itemstack = this.currentItem; this.currentItem = null; update(); return itemstack; } else { itemstack = this.currentItem.splitStack(amount); if (this.currentItem.stackSize == 0) this.currentItem = null; update(); return itemstack; } } else return null; } @Override public ItemStack getStackInSlotOnClosing(int slot) { if (this.currentItem != null) { ItemStack itemstack = this.currentItem; this.currentItem = null; update(); return itemstack; } else return null; } @Override public void setInventorySlotContents(int slot, ItemStack stack) { this.currentItem = stack; if (stack != null && stack.stackSize > this.getInventoryStackLimit()) { stack.stackSize = this.getInventoryStackLimit(); } update(); } @Override public String getInventoryName() { return "Rift Injection Pool"; } @Override public boolean hasCustomInventoryName() { return false; } @Override public int getInventoryStackLimit() { return 16; } @Override public boolean isUseableByPlayer(EntityPlayer player) { return true; } @Override public void openInventory() { } @Override public void closeInventory() { } @Override public boolean isItemValidForSlot(int slot, ItemStack item) { return InjectorRegistry.hasRecipeForInput(item); } }