package mcjty.deepresonance.blocks.laser; import elec332.core.world.WorldHelper; import mcjty.deepresonance.DeepResonance; import mcjty.deepresonance.blocks.ModBlocks; import mcjty.deepresonance.blocks.lens.LensSetup; import mcjty.deepresonance.blocks.tank.TileTank; import mcjty.deepresonance.config.ConfigMachines; import mcjty.deepresonance.fluid.DRFluidRegistry; import mcjty.deepresonance.fluid.LiquidCrystalFluidTagData; import mcjty.lib.container.DefaultSidedInventory; import mcjty.lib.container.InventoryHelper; import mcjty.lib.entity.GenericEnergyReceiverTileEntity; import mcjty.lib.network.Argument; import mcjty.lib.network.PacketRequestIntegerFromServer; import mcjty.lib.varia.BlockTools; import mcjty.lib.varia.CustomSidedInvWrapper; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import java.util.HashMap; import java.util.Map; public class LaserTileEntity extends GenericEnergyReceiverTileEntity implements DefaultSidedInventory, ITickable { public static final String CMD_GETLIQUID = "getLiquid"; public static final String CLIENTCMD_GETLIQUID = "getLiquid"; public static final int COLOR_BLUE = 1; public static final int COLOR_RED = 2; public static final int COLOR_GREEN = 3; public static final int COLOR_YELLOW = 4; // This is rendered as off in meta // Transient private int tickCounter = 10; private int progressCounter = 0; private int color = 0; // 0 means not active, > 0 means a color laser private int crystalLiquid = 0; // This is not RCL but just liquidified spent crystal private int powered = 0; private static int crystalLiquidClient = 0; // Infusing bonus for items. Index is the registry name of the item. public static Map<String, InfusingBonus> infusingBonusMap = null; private InventoryHelper inventoryHelper = new InventoryHelper(this, LaserContainer.factory, 2); public LaserTileEntity() { super(ConfigMachines.Laser.rfMaximum, ConfigMachines.Laser.rfPerTick); } @Override public void setPowered(int powered) { if (this.powered != powered) { this.powered = powered; markDirty(); IBlockState state = worldObj.getBlockState(pos); worldObj.notifyBlockUpdate(pos, state, state, 3); } } @Override public InventoryHelper getInventoryHelper() { return inventoryHelper; } @Override public void update() { if (!worldObj.isRemote) { checkStateServer(); } } protected void checkStateServer() { tickCounter--; if (tickCounter > 0) { return; } tickCounter = 10; checkCrystal(); if (powered == 0) { changeColor(0); return; } ItemStack stack = inventoryHelper.getStackInSlot(LaserContainer.SLOT_CATALYST); InfusingBonus bonus = getInfusingBonus(stack); if (bonus == null) { changeColor(0); return; } if (getEnergyStored(null) < ConfigMachines.Laser.rfUsePerCatalyst) { changeColor(0); return; } if (crystalLiquid < ConfigMachines.Laser.crystalLiquidPerCatalyst) { changeColor(0); return; } BlockPos tankCoordinate = findLens(); if (tankCoordinate != null) { changeColor(bonus.getColor()); } else { changeColor(0); return; } progressCounter--; markDirty(); if (progressCounter > 0) { return; } progressCounter = ConfigMachines.Laser.ticks10PerCatalyst; infuseLiquid(tankCoordinate, bonus); } private boolean validRCLTank(TileTank tank) { Fluid fluid = DRFluidRegistry.getFluidFromStack(tank.getFluid()); return fluid == null || fluid == DRFluidRegistry.liquidCrystal; } private void infuseLiquid(BlockPos tankCoordinate, InfusingBonus bonus) { // We consume stuff even if the tank does not have enough liquid. Player has to be careful decrStackSize(LaserContainer.SLOT_CATALYST, 1); consumeEnergy(ConfigMachines.Laser.rfUsePerCatalyst); crystalLiquid -= ConfigMachines.Laser.crystalLiquidPerCatalyst; TileEntity te = WorldHelper.getTileAt(worldObj, tankCoordinate); if (te instanceof TileTank) { TileTank tileTank = (TileTank) te; if (validRCLTank(tileTank)) { FluidStack stack = tileTank.drain(null, ConfigMachines.Laser.rclPerCatalyst, false); if (stack != null) { stack = tileTank.drain(null, ConfigMachines.Laser.rclPerCatalyst, true); LiquidCrystalFluidTagData fluidData = LiquidCrystalFluidTagData.fromStack(stack); float purity = bonus.getPurityModifier().modify(fluidData.getPurity(), fluidData.getQuality()); float strength = bonus.getStrengthModifier().modify(fluidData.getStrength(), fluidData.getQuality()); float efficiency = bonus.getEfficiencyModifier().modify(fluidData.getEfficiency(), fluidData.getQuality()); fluidData.setPurity(purity); fluidData.setStrength(strength); fluidData.setEfficiency(efficiency); FluidStack newStack = fluidData.makeLiquidCrystalStack(); if (Math.abs(purity) < 0.01) { newStack.amount /= 10; } tileTank.fill(null, newStack, true); } } } } private void changeColor(int newcolor) { if (newcolor != color) { color = newcolor; int mcolor = color; if (color == COLOR_YELLOW) { mcolor = COLOR_RED; } else if (color == 0) { mcolor = 0; // Off } worldObj.setBlockState(getPos(), worldObj.getBlockState(getPos()).withProperty(LaserBlock.COLOR, mcolor), 3); markDirty(); } } public int getColor() { return color; } private void checkCrystal() { ItemStack stack = inventoryHelper.getStackInSlot(LaserContainer.SLOT_CRYSTAL); if (stack != null) { NBTTagCompound tagCompound = stack.getTagCompound(); float strength = tagCompound == null ? 0 : tagCompound.getFloat("strength") / 100.0f; int addAmount = (int) (ConfigMachines.Laser.minCrystalLiquidPerCrystal + strength * (ConfigMachines.Laser.maxCrystalLiquidPerCrystal - ConfigMachines.Laser.minCrystalLiquidPerCrystal)); int newAmount = crystalLiquid + addAmount; if (newAmount > ConfigMachines.Laser.crystalLiquidMaximum) { // Not enough room return; } inventoryHelper.decrStackSize(LaserContainer.SLOT_CRYSTAL, 1); crystalLiquid = newAmount; markDirty(); } } public static InfusingBonus getInfusingBonus(ItemStack item) { if (item == null) { return null; } String name = item.getItem().getRegistryName().getResourcePath(); // String name = Item.itemRegistry.getNameForObject(item.getItem()).toString(); return infusingBonusMap.get(name); } public static void createDefaultInfusionBonusMap() { infusingBonusMap = new HashMap<String, InfusingBonus>(); infusingBonusMap.put(Items.DIAMOND.getRegistryName().getResourcePath(), new InfusingBonus( COLOR_BLUE, new InfusingBonus.Modifier(5.0f, 100.0f), InfusingBonus.Modifier.NONE, InfusingBonus.Modifier.NONE)); infusingBonusMap.put(Items.EMERALD.getRegistryName().getResourcePath(), new InfusingBonus( COLOR_GREEN, new InfusingBonus.Modifier(8.0f, 100.0f), InfusingBonus.Modifier.NONE, InfusingBonus.Modifier.NONE)); infusingBonusMap.put(Items.ENDER_PEARL.getRegistryName().getResourcePath(), new InfusingBonus( COLOR_GREEN, new InfusingBonus.Modifier(2.0f, 100.0f), InfusingBonus.Modifier.NONE, InfusingBonus.Modifier.NONE)); infusingBonusMap.put(Items.REDSTONE.getRegistryName().getResourcePath(), new InfusingBonus( COLOR_RED, new InfusingBonus.Modifier(-1.0f, 0.0f), new InfusingBonus.Modifier(5.0f, 60.0f), InfusingBonus.Modifier.NONE)); infusingBonusMap.put(Items.GUNPOWDER.getRegistryName().getResourcePath(), new InfusingBonus( COLOR_RED, new InfusingBonus.Modifier(-5.0f, 0.0f), new InfusingBonus.Modifier(8.0f, 70.0f), new InfusingBonus.Modifier(4.0f, 60.0f))); infusingBonusMap.put(Items.GLOWSTONE_DUST.getRegistryName().getResourcePath(), new InfusingBonus( COLOR_YELLOW, new InfusingBonus.Modifier(-2.0f, 0.0f), new InfusingBonus.Modifier(6.0f, 50.0f), new InfusingBonus.Modifier(3.0f, 50.0f))); infusingBonusMap.put(Items.BLAZE_POWDER.getRegistryName().getResourcePath(), new InfusingBonus( COLOR_YELLOW, new InfusingBonus.Modifier(-6.0f, 0.0f), new InfusingBonus.Modifier(5.0f, 70.0f), new InfusingBonus.Modifier(5.0f, 70.0f))); infusingBonusMap.put(Items.QUARTZ.getRegistryName().getResourcePath(), new InfusingBonus( COLOR_BLUE, new InfusingBonus.Modifier(-1.0f, 0.0f), InfusingBonus.Modifier.NONE, new InfusingBonus.Modifier(7.0f, 80.0f))); infusingBonusMap.put(Items.NETHER_STAR.getRegistryName().getResourcePath(), new InfusingBonus( COLOR_RED, new InfusingBonus.Modifier(-60.0f, 0.0f), new InfusingBonus.Modifier(90.0f, 100.0f), new InfusingBonus.Modifier(90.0f, 100.0f))); infusingBonusMap.put(Items.GHAST_TEAR.getRegistryName().getResourcePath(), new InfusingBonus( COLOR_YELLOW, new InfusingBonus.Modifier(-20.0f, 0.0f), new InfusingBonus.Modifier(25.0f, 100.0f), new InfusingBonus.Modifier(15.0f, 100.0f))); infusingBonusMap.put(Items.PRISMARINE_SHARD.getRegistryName().getResourcePath(), new InfusingBonus( COLOR_YELLOW, InfusingBonus.Modifier.NONE, new InfusingBonus.Modifier(3.0f, 30.0f), new InfusingBonus.Modifier(3.0f, 30.0f))); infusingBonusMap.put(Items.PRISMARINE_CRYSTALS.getRegistryName().getResourcePath(), new InfusingBonus( COLOR_YELLOW, InfusingBonus.Modifier.NONE, new InfusingBonus.Modifier(4.0f, 35.0f), new InfusingBonus.Modifier(4.0f, 35.0f))); infusingBonusMap.put(Items.SLIME_BALL.getRegistryName().getResourcePath(), new InfusingBonus( COLOR_GREEN, InfusingBonus.Modifier.NONE, InfusingBonus.Modifier.NONE, new InfusingBonus.Modifier(-10.0f, 1.0f))); infusingBonusMap.put(Items.COAL.getRegistryName().getResourcePath(), new InfusingBonus( COLOR_RED, new InfusingBonus.Modifier(-1.0f, 0.0f), new InfusingBonus.Modifier(-10.0f, 0.0f), InfusingBonus.Modifier.NONE)); infusingBonusMap.put(Items.NETHER_WART.getRegistryName().getResourcePath(), new InfusingBonus( COLOR_RED, new InfusingBonus.Modifier(-3.0f, 0.0f), new InfusingBonus.Modifier(2.0f, 35.0f), new InfusingBonus.Modifier(-2.0f, 1.0f))); infusingBonusMap.put(Items.GOLD_INGOT.getRegistryName().getResourcePath(), new InfusingBonus( COLOR_RED, InfusingBonus.Modifier.NONE, new InfusingBonus.Modifier(-1.0f, 0.0f), new InfusingBonus.Modifier(1.0f, 30.0f))); infusingBonusMap.put(Items.IRON_INGOT.getRegistryName().getResourcePath(), new InfusingBonus( COLOR_RED, InfusingBonus.Modifier.NONE, new InfusingBonus.Modifier(-2.0f, 0.0f), new InfusingBonus.Modifier(1.0f, 20.0f))); infusingBonusMap.put(Items.SNOWBALL.getRegistryName().getResourcePath(), new InfusingBonus( COLOR_RED, new InfusingBonus.Modifier(1.0f, 30.0f), InfusingBonus.Modifier.NONE, new InfusingBonus.Modifier(1.0f, 40.0f))); } private BlockPos findLens() { if (!worldObj.isBlockLoaded(getPos())) { return null; } IBlockState state = worldObj.getBlockState(getPos()); int meta = state.getBlock().getMetaFromState(state); EnumFacing direction = BlockTools.getOrientationHoriz(meta); BlockPos shouldBeAir = getPos().offset(direction); if (!worldObj.isAirBlock(shouldBeAir)) { return null; } BlockPos shouldBeLens = shouldBeAir.offset(direction); Block lensBlock = WorldHelper.getBlockAt(worldObj, shouldBeLens); if (lensBlock != LensSetup.lensBlock) { return null; } EnumFacing lensDirection = BlockTools.getOrientationHoriz(WorldHelper.getBlockMeta(worldObj, shouldBeLens)); if (lensDirection != direction) { return null; } return shouldBeLens.offset(direction); } public void requestCrystalLiquidFromServer() { DeepResonance.networkHandler.getNetworkWrapper().sendToServer(new PacketRequestIntegerFromServer(DeepResonance.MODID, pos, CMD_GETLIQUID, CLIENTCMD_GETLIQUID)); } @SideOnly(Side.CLIENT) public static int getCrystalLiquidClient() { return crystalLiquidClient; } @Override public Integer executeWithResultInteger(String command, Map<String, Argument> args) { Integer rc = super.executeWithResultInteger(command, args); if (rc != null) { return rc; } if (CMD_GETLIQUID.equals(command)) { return crystalLiquid; } return null; } @Override public boolean execute(String command, Integer result) { boolean rc = super.execute(command, result); if (rc) { return true; } if (CLIENTCMD_GETLIQUID.equals(command)) { crystalLiquidClient = result; return true; } return false; } @Override public void readFromNBT(NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); color = tagCompound.getInteger("color"); progressCounter = tagCompound.getInteger("progress"); powered = tagCompound.getByte("powered"); } @Override public void readRestorableFromNBT(NBTTagCompound tagCompound) { super.readRestorableFromNBT(tagCompound); readBufferFromNBT(tagCompound, inventoryHelper); crystalLiquid = tagCompound.getInteger("liquid"); } @Override public void writeToNBT(NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); tagCompound.setInteger("color", color); tagCompound.setInteger("progress", progressCounter); tagCompound.setByte("powered", (byte) powered); } @Override public void writeRestorableToNBT(NBTTagCompound tagCompound) { super.writeRestorableToNBT(tagCompound); writeBufferToNBT(tagCompound, inventoryHelper); tagCompound.setInteger("liquid", crystalLiquid); } @Override public boolean shouldRenderInPass(int pass) { return pass == 1; } @SideOnly(Side.CLIENT) @Override public AxisAlignedBB getRenderBoundingBox() { // @todo needs a better box return new AxisAlignedBB(getPos().getX() - 3, getPos().getY() - 1, getPos().getZ() - 3, getPos().getX() + 4, getPos().getY() + 2, getPos().getZ() + 4); } @Override public boolean canExtractItem(int index, ItemStack item, EnumFacing side) { return false; } @Override public int[] getSlotsForFace(EnumFacing side) { return new int[]{LaserContainer.SLOT_CATALYST, LaserContainer.SLOT_CRYSTAL}; } @Override public boolean canInsertItem(int index, ItemStack item, EnumFacing side) { switch (index) { case LaserContainer.SLOT_CRYSTAL: return item.isItemEqual(new ItemStack(ModBlocks.resonatingCrystalBlock)); case LaserContainer.SLOT_CATALYST: return true; } return false; } @Override public int getInventoryStackLimit() { return 64; } @Override public boolean isUseableByPlayer(EntityPlayer player) { return canPlayerAccess(player); } @Override public boolean isItemValidForSlot(int index, ItemStack stack) { if (index == LaserContainer.SLOT_CRYSTAL) { return stack.getItem() == Item.getItemFromBlock(ModBlocks.resonatingCrystalBlock); } else { return true; } } IItemHandler invHandler = new CustomSidedInvWrapper(this); @Override public boolean hasCapability(Capability<?> capability, EnumFacing facing) { if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { return true; } return super.hasCapability(capability, facing); } @Override public <T> T getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, net.minecraft.util.EnumFacing facing) { if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { return (T) invHandler; } return super.getCapability(capability, facing); } }