From 5b4948342759307c0c7e398290b7ee4c0e779b18 Mon Sep 17 00:00:00 2001 From: Robert S Date: Sat, 27 Sep 2014 16:26:12 -0400 Subject: [PATCH] Converted Casting mold and Millstone to scala --- .../archaic/process/RenderCastingMold.java | 42 - .../archaic/process/RenderCastingMold.scala | 41 + .../archaic/process/RenderMillstone.java | 24 - .../archaic/process/RenderMillstone.scala | 24 + .../archaic/process/TileCastingMold.java | 198 ----- .../archaic/process/TileCastingMold.scala | 168 ++++ .../archaic/process/TileMillstone.java | 173 ---- .../archaic/process/TileMillstone.scala | 151 ++++ .../electrical/tesla/TileTesla.java | 774 ------------------ .../electrical/tesla/TileTesla.scala | 655 +++++++++++++++ 10 files changed, 1039 insertions(+), 1211 deletions(-) delete mode 100644 src/main/scala/resonantinduction/archaic/process/RenderCastingMold.java create mode 100644 src/main/scala/resonantinduction/archaic/process/RenderCastingMold.scala delete mode 100644 src/main/scala/resonantinduction/archaic/process/RenderMillstone.java create mode 100644 src/main/scala/resonantinduction/archaic/process/RenderMillstone.scala delete mode 100644 src/main/scala/resonantinduction/archaic/process/TileCastingMold.java create mode 100644 src/main/scala/resonantinduction/archaic/process/TileCastingMold.scala delete mode 100644 src/main/scala/resonantinduction/archaic/process/TileMillstone.java create mode 100644 src/main/scala/resonantinduction/archaic/process/TileMillstone.scala delete mode 100644 src/main/scala/resonantinduction/electrical/tesla/TileTesla.java create mode 100644 src/main/scala/resonantinduction/electrical/tesla/TileTesla.scala diff --git a/src/main/scala/resonantinduction/archaic/process/RenderCastingMold.java b/src/main/scala/resonantinduction/archaic/process/RenderCastingMold.java deleted file mode 100644 index e3e5f840e..000000000 --- a/src/main/scala/resonantinduction/archaic/process/RenderCastingMold.java +++ /dev/null @@ -1,42 +0,0 @@ -package resonantinduction.archaic.process; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.client.model.AdvancedModelLoader; -import net.minecraftforge.client.model.IModelCustom; -import org.lwjgl.opengl.GL11; -import resonant.lib.render.RenderItemOverlayUtility; -import resonant.lib.render.RenderUtility; -import resonantinduction.core.Reference; - -@SideOnly(Side.CLIENT) -public class RenderCastingMold extends TileEntitySpecialRenderer -{ - public static final IModelCustom MODEL = AdvancedModelLoader.loadModel(new ResourceLocation(Reference.domain(), Reference.modelPath() + "castingMold.tcn")); - public static RenderCastingMold INSTANCE = new RenderCastingMold(); - - @Override - public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float var8) - { - if (tileEntity instanceof TileCastingMold) - { - TileCastingMold tile = (TileCastingMold) tileEntity; - - GL11.glPushMatrix(); - GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5); - GL11.glTranslated(0, -0.25, 0); - GL11.glScalef(0.5f, 0.5f, 0.5f); - RenderUtility.bind(Reference.domain(), Reference.modelPath() + "castingMold.png"); - MODEL.renderAll(); - GL11.glPopMatrix(); - - if (tile.getWorldObj() != null) - { - RenderItemOverlayUtility.renderItemOnSides(tileEntity, tile.getStackInSlot(0), x, y, z, ""); - } - } - } -} diff --git a/src/main/scala/resonantinduction/archaic/process/RenderCastingMold.scala b/src/main/scala/resonantinduction/archaic/process/RenderCastingMold.scala new file mode 100644 index 000000000..479360346 --- /dev/null +++ b/src/main/scala/resonantinduction/archaic/process/RenderCastingMold.scala @@ -0,0 +1,41 @@ +package resonantinduction.archaic.process + +import cpw.mods.fml.relauncher.Side +import cpw.mods.fml.relauncher.SideOnly +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer +import net.minecraft.tileentity.TileEntity +import net.minecraft.util.ResourceLocation +import net.minecraftforge.client.model.AdvancedModelLoader +import net.minecraftforge.client.model.IModelCustom +import org.lwjgl.opengl.GL11 +import resonant.lib.render.RenderItemOverlayUtility +import resonant.lib.render.RenderUtility +import resonantinduction.core.Reference + +@SideOnly(Side.CLIENT) object RenderCastingMold +{ + final val MODEL: IModelCustom = AdvancedModelLoader.loadModel(new ResourceLocation(Reference.domain, Reference.modelPath + "castingMold.tcn")) + var INSTANCE: RenderCastingMold = new RenderCastingMold +} + +@SideOnly(Side.CLIENT) class RenderCastingMold extends TileEntitySpecialRenderer +{ + def renderTileEntityAt(tileEntity: TileEntity, x: Double, y: Double, z: Double, var8: Float) + { + if (tileEntity.isInstanceOf[TileCastingMold]) + { + val tile: TileCastingMold = tileEntity.asInstanceOf[TileCastingMold] + GL11.glPushMatrix + GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5) + GL11.glTranslated(0, -0.25, 0) + GL11.glScalef(0.5f, 0.5f, 0.5f) + RenderUtility.bind(Reference.domain, Reference.modelPath + "castingMold.png") + RenderCastingMold.MODEL.renderAll + GL11.glPopMatrix + if (tile.getWorldObj != null) + { + RenderItemOverlayUtility.renderItemOnSides(tileEntity, tile.getStackInSlot(0), x, y, z, "") + } + } + } +} \ No newline at end of file diff --git a/src/main/scala/resonantinduction/archaic/process/RenderMillstone.java b/src/main/scala/resonantinduction/archaic/process/RenderMillstone.java deleted file mode 100644 index 730b5f519..000000000 --- a/src/main/scala/resonantinduction/archaic/process/RenderMillstone.java +++ /dev/null @@ -1,24 +0,0 @@ -package resonantinduction.archaic.process; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; -import net.minecraft.tileentity.TileEntity; -import resonant.lib.render.RenderItemOverlayUtility; - -@SideOnly(Side.CLIENT) -public class RenderMillstone extends TileEntitySpecialRenderer -{ - private final RenderBlocks renderBlocks = new RenderBlocks(); - - @Override - public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float var8) - { - if (tileEntity instanceof TileMillstone) - { - TileMillstone tile = (TileMillstone) tileEntity; - RenderItemOverlayUtility.renderItemOnSides(tileEntity, tile.getStackInSlot(0), x, y, z, ""); - } - } -} diff --git a/src/main/scala/resonantinduction/archaic/process/RenderMillstone.scala b/src/main/scala/resonantinduction/archaic/process/RenderMillstone.scala new file mode 100644 index 000000000..0371d02db --- /dev/null +++ b/src/main/scala/resonantinduction/archaic/process/RenderMillstone.scala @@ -0,0 +1,24 @@ +package resonantinduction.archaic.process + +import cpw.mods.fml.relauncher.Side +import cpw.mods.fml.relauncher.SideOnly +import net.minecraft.client.renderer.RenderBlocks +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer +import net.minecraft.tileentity.TileEntity +import resonant.lib.render.RenderItemOverlayUtility + +@SideOnly(Side.CLIENT) +class RenderMillstone extends TileEntitySpecialRenderer +{ + private final val renderBlocks: RenderBlocks = new RenderBlocks + + def renderTileEntityAt(tileEntity: TileEntity, x: Double, y: Double, z: Double, var8: Float) + { + if (tileEntity.isInstanceOf[TileMillstone]) + { + val tile: TileMillstone = tileEntity.asInstanceOf[TileMillstone] + RenderItemOverlayUtility.renderItemOnSides(tileEntity, tile.getStackInSlot(0), x, y, z, "") + } + } + +} \ No newline at end of file diff --git a/src/main/scala/resonantinduction/archaic/process/TileCastingMold.java b/src/main/scala/resonantinduction/archaic/process/TileCastingMold.java deleted file mode 100644 index 127e6e0ba..000000000 --- a/src/main/scala/resonantinduction/archaic/process/TileCastingMold.java +++ /dev/null @@ -1,198 +0,0 @@ -package resonantinduction.archaic.process; - -import cpw.mods.fml.common.network.ByteBufUtils; -import io.netty.buffer.ByteBuf; -import net.minecraft.block.material.Material; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.fluids.*; -import resonant.api.recipe.MachineRecipes; -import resonant.api.recipe.RecipeResource; -import resonant.content.factory.resources.RecipeType; -import resonant.lib.content.prefab.java.TileInventory; -import resonant.lib.network.discriminator.PacketTile; -import resonant.lib.network.discriminator.PacketType; -import resonant.lib.network.handle.IPacketReceiver; -import resonant.lib.utility.FluidUtility; -import resonant.lib.utility.inventory.InventoryUtility; -import resonantinduction.core.Reference; -import universalelectricity.core.transform.vector.Vector3; - -/** - * Turns molten fuilds into ingots. - *

- * 1 m^3 of molten fluid = 1 block - * Approximately 100-110 L of fluid = 1 ingot. - * - * @author Calclavia - */ -public class TileCastingMold extends TileInventory implements IFluidHandler, IPacketReceiver -{ - private final int amountPerIngot = 100; - protected FluidTank tank = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME); - - public TileCastingMold() - { - super(Material.rock); - setTextureName(Reference.prefix() + "material_metal_side"); - normalRender(false); - isOpaqueCube(false); - } - - @Override - public boolean canUpdate() - { - return false; - } - - @Override - public PacketTile getDescPacket() - { - NBTTagCompound nbt = new NBTTagCompound(); - this.writeToNBT(nbt); - return new PacketTile(this, nbt); - } - - @Override - public void read(ByteBuf data, EntityPlayer player, PacketType type) - { - try - { - this.readFromNBT(ByteBufUtils.readTag(data)); - } - catch (Exception e) - { - e.printStackTrace(); - } - } - - public void onInventoryChanged() - { - if (worldObj != null) - { - worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); - } - } - - public void update() - { - /** - * Check blocks above for fluid. - */ - Vector3 checkPos = new Vector3(this).add(0, 1, 0); - FluidStack drainStack = FluidUtility.drainBlock(worldObj, checkPos, false); - - if (MachineRecipes.INSTANCE.getOutput(RecipeType.SMELTER.name(), drainStack).length > 0) - { - if (drainStack.amount == tank.fill(drainStack, false)) - { - tank.fill(FluidUtility.drainBlock(worldObj, checkPos, true), true); - } - } - - /** - * Attempt to cast the fluid - */ - while (tank.getFluidAmount() >= amountPerIngot && (getStackInSlot(0) == null || getStackInSlot(0).stackSize < getStackInSlot(0).getMaxStackSize())) - { - RecipeResource[] outputs = MachineRecipes.INSTANCE.getOutput(RecipeType.SMELTER.name(), tank.getFluid()); - - for (RecipeResource output : outputs) - { - incrStackSize(0, output.getItemStack()); - } - - tank.drain(amountPerIngot, true); - } - } - - @Override - public void readFromNBT(NBTTagCompound tag) - { - super.readFromNBT(tag); - tank.writeToNBT(tag); - } - - @Override - public void writeToNBT(NBTTagCompound tag) - { - super.writeToNBT(tag); - tank.readFromNBT(tag); - } - - /* IFluidHandler */ - @Override - public int fill(ForgeDirection from, FluidStack resource, boolean doFill) - { - int fill = tank.fill(resource, doFill); - updateEntity(); - return fill; - } - - @Override - public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) - { - return null; - } - - @Override - public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) - { - return null; - } - - @Override - public boolean canFill(ForgeDirection from, Fluid fluid) - { - return fluid != null && fluid.getName().contains("molten"); - } - - @Override - public boolean canDrain(ForgeDirection from, Fluid fluid) - { - return false; - } - - @Override - public FluidTankInfo[] getTankInfo(ForgeDirection from) - { - return new FluidTankInfo[] { tank.getInfo() }; - } - - @Override - public void click(EntityPlayer player) - { - if (!world().isRemote) - { - - ItemStack output = getStackInSlot(0); - - if (output != null) - { - InventoryUtility.dropItemStack(world(), new Vector3(player), output, 0); - setInventorySlotContents(0, null); - } - - onInventoryChanged(); - } - } - - @Override - public boolean use(EntityPlayer player, int hitSide, Vector3 hit) - { - update(); - - ItemStack current = player.inventory.getCurrentItem(); - ItemStack output = getStackInSlot(0); - - if (output != null) - { - InventoryUtility.dropItemStack(world(), new Vector3(player), output, 0); - setInventorySlotContents(0, null); - } - - return true; - } -} diff --git a/src/main/scala/resonantinduction/archaic/process/TileCastingMold.scala b/src/main/scala/resonantinduction/archaic/process/TileCastingMold.scala new file mode 100644 index 000000000..627fd26e3 --- /dev/null +++ b/src/main/scala/resonantinduction/archaic/process/TileCastingMold.scala @@ -0,0 +1,168 @@ +package resonantinduction.archaic.process + +import cpw.mods.fml.common.network.ByteBufUtils +import io.netty.buffer.ByteBuf +import net.minecraft.block.material.Material +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.item.ItemStack +import net.minecraft.nbt.NBTTagCompound +import net.minecraftforge.common.util.ForgeDirection +import net.minecraftforge.fluids._ +import resonant.api.recipe.MachineRecipes +import resonant.api.recipe.RecipeResource +import resonant.content.factory.resources.RecipeType +import resonant.lib.content.prefab.java.TileInventory +import resonant.lib.network.discriminator.PacketTile +import resonant.lib.network.discriminator.PacketType +import resonant.lib.network.handle.IPacketReceiver +import resonant.lib.utility.FluidUtility +import resonant.lib.utility.inventory.InventoryUtility +import resonantinduction.core.Reference +import universalelectricity.core.transform.vector.Vector3 + +/** + * Turns molten fuilds into ingots. + *

+ * 1 cubed meter of molten fluid = 1 block + * Approximately 100-110 L of fluid = 1 ingot. + + * @author Calclavia + */ +class TileCastingMold extends TileInventory(Material.rock) with IFluidHandler with IPacketReceiver +{ + private final val amountPerIngot: Int = 100 + protected var tank: FluidTank = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME) + + //Constructor + setTextureName(Reference.prefix + "material_metal_side") + normalRender(false) + isOpaqueCube(false) + + override def canUpdate: Boolean = + { + return false + } + + override def getDescPacket: PacketTile = + { + val nbt: NBTTagCompound = new NBTTagCompound + this.writeToNBT(nbt) + return new PacketTile(this, nbt) + } + + def read(data: ByteBuf, player: EntityPlayer, `type`: PacketType) + { + try + { + this.readFromNBT(ByteBufUtils.readTag(data)) + } + catch + { + case e: Exception => + { + e.printStackTrace + } + } + } + + override def onInventoryChanged + { + if (worldObj != null) + { + worldObj.markBlockForUpdate(xCoord, yCoord, zCoord) + } + } + + override def update + { + val checkPos: Vector3 = new Vector3(this).add(0, 1, 0) + val drainStack: FluidStack = FluidUtility.drainBlock(worldObj, checkPos, false) + if (MachineRecipes.INSTANCE.getOutput(RecipeType.SMELTER.name, drainStack).length > 0) + { + if (drainStack.amount == tank.fill(drainStack, false)) + { + tank.fill(FluidUtility.drainBlock(worldObj, checkPos, true), true) + } + } + while (tank.getFluidAmount >= amountPerIngot && (getStackInSlot(0) == null || getStackInSlot(0).stackSize < getStackInSlot(0).getMaxStackSize)) + { + val outputs: Array[RecipeResource] = MachineRecipes.INSTANCE.getOutput(RecipeType.SMELTER.name, tank.getFluid) + for (output <- outputs) + { + incrStackSize(0, output.getItemStack) + } + tank.drain(amountPerIngot, true) + } + } + + override def readFromNBT(tag: NBTTagCompound) + { + super.readFromNBT(tag) + tank.writeToNBT(tag) + } + + override def writeToNBT(tag: NBTTagCompound) + { + super.writeToNBT(tag) + tank.readFromNBT(tag) + } + + def fill(from: ForgeDirection, resource: FluidStack, doFill: Boolean): Int = + { + val fill: Int = tank.fill(resource, doFill) + updateEntity + return fill + } + + def drain(from: ForgeDirection, resource: FluidStack, doDrain: Boolean): FluidStack = + { + return null + } + + def drain(from: ForgeDirection, maxDrain: Int, doDrain: Boolean): FluidStack = + { + return null + } + + def canFill(from: ForgeDirection, fluid: Fluid): Boolean = + { + return fluid != null && fluid.getName.contains("molten") + } + + def canDrain(from: ForgeDirection, fluid: Fluid): Boolean = + { + return false + } + + def getTankInfo(from: ForgeDirection): Array[FluidTankInfo] = + { + return Array[FluidTankInfo](tank.getInfo) + } + + override def click(player: EntityPlayer) + { + if (!world.isRemote) + { + val output: ItemStack = getStackInSlot(0) + if (output != null) + { + InventoryUtility.dropItemStack(world, new Vector3(player), output, 0) + setInventorySlotContents(0, null) + } + onInventoryChanged + } + } + + override def use(player: EntityPlayer, hitSide: Int, hit: Vector3): Boolean = + { + update + val current: ItemStack = player.inventory.getCurrentItem + val output: ItemStack = getStackInSlot(0) + if (output != null) + { + InventoryUtility.dropItemStack(world, new Vector3(player), output, 0) + setInventorySlotContents(0, null) + } + return true + } +} \ No newline at end of file diff --git a/src/main/scala/resonantinduction/archaic/process/TileMillstone.java b/src/main/scala/resonantinduction/archaic/process/TileMillstone.java deleted file mode 100644 index 037004e71..000000000 --- a/src/main/scala/resonantinduction/archaic/process/TileMillstone.java +++ /dev/null @@ -1,173 +0,0 @@ -package resonantinduction.archaic.process; - -import cpw.mods.fml.common.network.ByteBufUtils; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import io.netty.buffer.ByteBuf; -import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.IIcon; -import net.minecraftforge.common.util.ForgeDirection; -import resonant.api.recipe.MachineRecipes; -import resonant.api.recipe.RecipeResource; -import resonant.content.factory.resources.RecipeType; -import resonant.content.spatial.block.SpatialBlock; -import resonant.lib.content.prefab.java.TileInventory; -import resonant.lib.network.discriminator.PacketTile; -import resonant.lib.network.discriminator.PacketType; -import resonant.lib.network.handle.IPacketReceiver; -import resonant.lib.utility.inventory.InventoryUtility; -import resonantinduction.core.Reference; -import resonantinduction.mechanical.mech.gear.ItemHandCrank; -import universalelectricity.core.transform.vector.Vector3; - -public class TileMillstone extends TileInventory implements IPacketReceiver -{ - private int grindCount = 0; - - public TileMillstone() - { - super(Material.rock); - setTextureName(Reference.prefix() + "millstone_side"); - } - - public void onInventoryChanged() - { - grindCount = 0; - worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); - } - - public void doGrind(Vector3 spawnPos) - { - RecipeResource[] outputs = MachineRecipes.INSTANCE.getOutput(RecipeType.GRINDER.name(), getStackInSlot(0)); - - if (outputs.length > 0) - { - if (++grindCount > 20) - { - for (RecipeResource res : outputs) - { - InventoryUtility.dropItemStack(worldObj, spawnPos, res.getItemStack().copy()); - } - - decrStackSize(0, 1); - onInventoryChanged(); - } - } - } - - @Override - public boolean canUpdate() - { - return false; - } - - @Override - public boolean isItemValidForSlot(int i, ItemStack itemStack) - { - return MachineRecipes.INSTANCE.getOutput(RecipeType.GRINDER.name(), itemStack).length > 0; - } - - @Override - public boolean canStore(ItemStack stack, int slot, ForgeDirection side) - { - return true; - } - - /** - * Packets - */ - @Override - public PacketTile getDescPacket() - { - NBTTagCompound nbt = new NBTTagCompound(); - this.writeToNBT(nbt); - return new PacketTile(this, nbt); - } - - @Override - public void read(ByteBuf data, EntityPlayer player, PacketType type) - { - try - { - this.readFromNBT(ByteBufUtils.readTag(data)); - } - catch (Exception e) - { - e.printStackTrace(); - } - } - - @SideOnly(Side.CLIENT) - @Override - public void registerIcons(IIconRegister iconReg) - { - SpatialBlock.icon().put("millstone_side", iconReg.registerIcon(Reference.prefix() + "millstone_side")); - SpatialBlock.icon().put("millstone_top", iconReg.registerIcon(Reference.prefix() + "millstone_top")); - } - - @Override - @SideOnly(Side.CLIENT) - public IIcon getIcon(int side, int meta) - { - if (side == 0 || side == 1) - { - return SpatialBlock.icon().get("millstone_top"); - } - - return SpatialBlock.icon().get("millstone_side"); - } - - @Override - public void click(EntityPlayer player) - { - if (!world().isRemote) - { - - ItemStack output = getStackInSlot(0); - - if (output != null) - { - InventoryUtility.dropItemStack(world(), new Vector3(player), output, 0); - setInventorySlotContents(0, null); - } - - onInventoryChanged(); - } - } - - @Override - public boolean use(EntityPlayer player, int hitSide, Vector3 hit) - { - ItemStack current = player.inventory.getCurrentItem(); - ItemStack output = getStackInSlot(0); - - if (current != null && current.getItem() instanceof ItemHandCrank) - { - if (output != null) - { - doGrind(new Vector3(player)); - player.addExhaustion(0.3f); - return true; - } - } - - if (output != null) - { - InventoryUtility.dropItemStack(world(), new Vector3(player), output, 0); - setInventorySlotContents(0, null); - } - else if (current != null && isItemValidForSlot(0, current)) - { - setInventorySlotContents(0, current); - player.inventory.setInventorySlotContents(player.inventory.currentItem, null); - } - - world().markBlockForUpdate(x(), y(), z()); - - return false; - } -} diff --git a/src/main/scala/resonantinduction/archaic/process/TileMillstone.scala b/src/main/scala/resonantinduction/archaic/process/TileMillstone.scala new file mode 100644 index 000000000..6f8b6b20a --- /dev/null +++ b/src/main/scala/resonantinduction/archaic/process/TileMillstone.scala @@ -0,0 +1,151 @@ +package resonantinduction.archaic.process + +import cpw.mods.fml.common.network.ByteBufUtils +import cpw.mods.fml.relauncher.{Side, SideOnly} +import io.netty.buffer.ByteBuf +import net.minecraft.block.material.Material +import net.minecraft.client.renderer.texture.IIconRegister +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.item.ItemStack +import net.minecraft.nbt.NBTTagCompound +import net.minecraft.util.IIcon +import net.minecraftforge.common.util.ForgeDirection +import resonant.api.recipe.{MachineRecipes, RecipeResource} +import resonant.content.factory.resources.RecipeType +import resonant.content.spatial.block.SpatialBlock +import resonant.lib.content.prefab.java.TileInventory +import resonant.lib.network.discriminator.{PacketTile, PacketType} +import resonant.lib.network.handle.IPacketReceiver +import resonant.lib.utility.inventory.InventoryUtility +import resonantinduction.core.Reference +import resonantinduction.mechanical.mech.gear.ItemHandCrank +import universalelectricity.core.transform.vector.Vector3 + +class TileMillstone extends TileInventory(Material.rock) with IPacketReceiver +{ + + private var grindCount: Int = 0 + + //Constructor + setTextureName(Reference.prefix + "millstone_side") + + override def onInventoryChanged + { + grindCount = 0 + worldObj.markBlockForUpdate(xCoord, yCoord, zCoord) + } + + def doGrind(spawnPos: Vector3) + { + val outputs: Array[RecipeResource] = MachineRecipes.INSTANCE.getOutput(RecipeType.GRINDER.name, getStackInSlot(0)) + if (outputs.length > 0) + { + grindCount += 1; + if ( grindCount > 20) + { + for (res <- outputs) + { + InventoryUtility.dropItemStack(worldObj, spawnPos, res.getItemStack.copy) + } + decrStackSize(0, 1) + onInventoryChanged + } + } + } + + override def canUpdate: Boolean = + { + return false + } + + override def isItemValidForSlot(i: Int, itemStack: ItemStack): Boolean = + { + return MachineRecipes.INSTANCE.getOutput(RecipeType.GRINDER.name, itemStack).length > 0 + } + + override def canStore(stack: ItemStack, slot: Int, side: ForgeDirection): Boolean = + { + return true + } + + /** + * Packets + */ + override def getDescPacket: PacketTile = + { + val nbt: NBTTagCompound = new NBTTagCompound + this.writeToNBT(nbt) + return new PacketTile(this, nbt) + } + + def read(data: ByteBuf, player: EntityPlayer, `type`: PacketType) + { + try + { + this.readFromNBT(ByteBufUtils.readTag(data)) + } + catch + { + case e: Exception => + { + e.printStackTrace + } + } + } + + @SideOnly(Side.CLIENT) override def registerIcons(iconReg: IIconRegister) + { + SpatialBlock.icon.put("millstone_side", iconReg.registerIcon(Reference.prefix + "millstone_side")) + SpatialBlock.icon.put("millstone_top", iconReg.registerIcon(Reference.prefix + "millstone_top")) + } + + @SideOnly(Side.CLIENT) override def getIcon(side: Int, meta: Int): IIcon = + { + if (side == 0 || side == 1) + { + return SpatialBlock.icon.get("millstone_top") + } + return SpatialBlock.icon.get("millstone_side") + } + + override def click(player: EntityPlayer) + { + if (!world.isRemote) + { + val output: ItemStack = getStackInSlot(0) + if (output != null) + { + InventoryUtility.dropItemStack(world, new Vector3(player), output, 0) + setInventorySlotContents(0, null) + } + onInventoryChanged + } + } + + override def use(player: EntityPlayer, hitSide: Int, hit: Vector3): Boolean = + { + val current: ItemStack = player.inventory.getCurrentItem + val output: ItemStack = getStackInSlot(0) + if (current != null && current.getItem.isInstanceOf[ItemHandCrank]) + { + if (output != null) + { + doGrind(new Vector3(player)) + player.addExhaustion(0.3f) + return true + } + } + if (output != null) + { + InventoryUtility.dropItemStack(world, new Vector3(player), output, 0) + setInventorySlotContents(0, null) + } + else if (current != null && isItemValidForSlot(0, current)) + { + setInventorySlotContents(0, current) + player.inventory.setInventorySlotContents(player.inventory.currentItem, null) + } + world.markBlockForUpdate(x, y, z) + return false + } +} \ No newline at end of file diff --git a/src/main/scala/resonantinduction/electrical/tesla/TileTesla.java b/src/main/scala/resonantinduction/electrical/tesla/TileTesla.java deleted file mode 100644 index 6c55c0e9d..000000000 --- a/src/main/scala/resonantinduction/electrical/tesla/TileTesla.java +++ /dev/null @@ -1,774 +0,0 @@ -/** - * - */ -package resonantinduction.electrical.tesla; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.PriorityQueue; -import java.util.Set; - -import cpw.mods.fml.common.network.ByteBufUtils; -import io.netty.buffer.ByteBuf; -import net.minecraft.block.Block; -import net.minecraft.block.material.Material; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.server.MinecraftServer; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ChatComponentText; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; -import resonant.lib.multiblock.reference.IMultiBlockStructure; -import resonant.lib.multiblock.reference.MultiBlockHandler; -import resonant.lib.network.discriminator.PacketTile; -import resonant.lib.network.discriminator.PacketType; -import resonant.lib.network.handle.IPacketReceiver; -import resonant.lib.render.EnumColor; -import resonant.lib.utility.LanguageUtility; -import resonant.lib.utility.LinkUtility; -import resonantinduction.core.Reference; -import resonantinduction.core.Settings; -import resonantinduction.core.util.ResonantUtil; -import resonantinduction.electrical.Electrical; -import universalelectricity.core.transform.vector.Vector3; - -import resonant.lib.content.prefab.java.TileElectric; -import universalelectricity.core.transform.vector.VectorWorld; - -/** - * The Tesla TileEntity. - * - * - Redstone (Prevent Output Toggle) - Right click (Prevent Input Toggle) - * - * @author Calclavia - * - */ -public class TileTesla extends TileElectric implements IMultiBlockStructure, ITesla, IPacketReceiver -{ - public final static int DEFAULT_COLOR = 12; - public final double TRANSFER_CAP = 10000D; - private int dyeID = DEFAULT_COLOR; - - private boolean canReceive = true; - private boolean attackEntities = true; - - /** Client side to do sparks */ - private boolean doTransfer = true; - - /** Prevents transfer loops */ - private final Set outputBlacklist = new HashSet(); - private final Set connectedTeslas = new HashSet(); - - /** - * Multiblock Methods. - */ - private MultiBlockHandler multiBlock; - - /** - * Quantum Tesla - */ - public Vector3 linked; - public int linkDim; - - /** - * Client - */ - private int zapCounter = 0; - private boolean isLinkedClient; - private boolean isTransfering; - - private TileTesla topCache; - - public TileTesla() - { - super(Material.iron); - setCapacity(TRANSFER_CAP * 2); - setMaxTransfer(TRANSFER_CAP); - setTextureName(Reference.prefix() + "material_metal_side"); - normalRender(false); - isOpaqueCube(false); - //this.saveIOMap(true); - } - - @Override - public void start() - { - super.start(); - TeslaGrid.instance().register(this); - } - - @Override - public void update() - { - super.update(); - - boolean doPacketUpdate = energy().getEnergy() > 0; - - /** - * Only transfer if it is the controlling Tesla tower. - */ - if (this.getMultiBlock().isPrimary()) - { - if (this.ticks() % (4 + this.worldObj.rand.nextInt(2)) == 0 && ((this.worldObj.isRemote && isTransfering) || (!this.energy().isEmpty() && !this.worldObj.isBlockIndirectlyGettingPowered(this.xCoord, this.yCoord, this.zCoord)))) - { - final TileTesla topTesla = this.getTopTelsa(); - final Vector3 topTeslaVector = new Vector3(topTesla); - - if (this.linked != null || this.isLinkedClient) - { - /** - * Quantum transportation. - */ - if (!this.worldObj.isRemote) - { - World dimWorld = MinecraftServer.getServer().worldServerForDimension(this.linkDim); - - if (dimWorld != null) - { - TileEntity transferTile = this.linked.getTileEntity(dimWorld); - - if (transferTile instanceof TileTesla && !transferTile.isInvalid()) - { - this.transfer(((TileTesla) transferTile), Math.min(energy().getEnergy(), TRANSFER_CAP)); - - if (this.zapCounter % 5 == 0 && Settings.SOUND_FXS()) - { - this.worldObj.playSoundEffect(this.xCoord + 0.5, this.yCoord + 0.5, this.zCoord + 0.5, Reference.prefix() + "electricshock", (float) this.energy().getEnergy() / (float) TRANSFER_CAP, 1.3f - 0.5f * (this.dyeID / 16f)); - } - } - } - } - else - { - Electrical.proxy().renderElectricShock(this.worldObj, topTeslaVector.clone().add(0.5), topTeslaVector.clone().add(new Vector3(0.5, Double.POSITIVE_INFINITY, 0.5)), false); - } - } - else - { - /** - * Normal transportation - */ - PriorityQueue teslaToTransfer = new PriorityQueue(1024, new Comparator() - { - public int compare(ITesla o1, ITesla o2) - { - double distance1 = new Vector3(topTesla).distance(new Vector3((TileEntity) o1)); - double distance2 = new Vector3(topTesla).distance(new Vector3((TileEntity) o2)); - - if (distance1 < distance2) - { - return 1; - } - else if (distance1 > distance2) - { - return -1; - } - - return 0; - } - }); - - for (ITesla otherTesla : TeslaGrid.instance().get()) - { - if (new Vector3((TileEntity) otherTesla).distance(new Vector3(this)) < this.getRange() && otherTesla != this) - { - if (otherTesla instanceof TileTesla) - { - if (((TileTesla) otherTesla).getHeight() <= 1) - { - continue; - } - - otherTesla = ((TileTesla) otherTesla).getMultiBlock().get(); - } - - /** - * Make sure Tesla is not part of this tower. - */ - if (!connectedTeslas.contains(otherTesla) && otherTesla != this && otherTesla.canTeslaTransfer(this) && canTeslaTransfer((TileEntity) otherTesla)) - { - teslaToTransfer.add(otherTesla); - } - } - } - - if (teslaToTransfer.size() > 0) - { - double transferEnergy = this.energy().getEnergy() / teslaToTransfer.size(); - - boolean sentPacket = false; - - for (int count = 0; count < 10; count++) - { - if (!teslaToTransfer.isEmpty()) - { - ITesla tesla = teslaToTransfer.poll(); - - if (this.zapCounter % 5 == 0 && Settings.SOUND_FXS()) - { - this.worldObj.playSoundEffect(this.xCoord + 0.5, this.yCoord + 0.5, this.zCoord + 0.5, Reference.prefix() + "electricshock", (float) this.energy().getEnergy() / (float) TRANSFER_CAP, 1.3f - 0.5f * (this.dyeID / 16f)); - } - - Vector3 targetVector = new Vector3((TileEntity) tesla); - int heightRange = 1; - - if (tesla instanceof TileTesla) - { - getMultiBlock().get().outputBlacklist.add(this); - targetVector = new Vector3(((TileTesla) tesla).getTopTelsa()); - heightRange = ((TileTesla) tesla).getHeight(); - } - - double distance = topTeslaVector.distance(targetVector); - - Electrical.proxy().renderElectricShock(this.worldObj, new Vector3(topTesla).add(new Vector3(0.5)), targetVector.add(new Vector3(0.5, Math.random() * heightRange / 3 - heightRange / 3, 0.5)), EnumColor.DYES[this.dyeID].toColor()); - - this.transfer(tesla, Math.min(transferEnergy, TRANSFER_CAP)); - - if (!sentPacket && transferEnergy > 0) - { - this.sendPacket(3); - } - } - } - } - } - - this.zapCounter++; - this.outputBlacklist.clear(); - - this.doTransfer = false; - } - - if (!this.worldObj.isRemote && this.energy().didEnergyStateChange()) - { - this.sendPacket(2); - } - } - - this.topCache = null; - } - - private void transfer(ITesla tesla, double transferEnergy) - { - if (transferEnergy > 0) - { - tesla.teslaTransfer(transferEnergy, true); - this.teslaTransfer(-transferEnergy, true); - } - } - - @Override - public boolean canTeslaTransfer(TileEntity tileEntity) - { - - if (tileEntity instanceof TileTesla) - { - TileTesla otherTesla = (TileTesla) tileEntity; - // Make sure Tesla is the same color - if (!(otherTesla.dyeID == dyeID || (otherTesla.dyeID == DEFAULT_COLOR || dyeID == DEFAULT_COLOR))) - { - return false; - } - } - - return canReceive && tileEntity != getMultiBlock().get() && !this.outputBlacklist.contains(tileEntity); - - } - - public void sendPacket(int type) - { - sendPacket(new PacketTile(this, this.getPacketData(type).toArray())); - } - - @Override - public PacketTile getDescPacket() - { - return new PacketTile(this, this.getPacketData(1).toArray()); - } - - /** - * 1 - Description Packet - * 2 - Energy Update - * 3 - Tesla Beam - */ - public ArrayList getPacketData(int type) - { - ArrayList data = new ArrayList(); - data.add((byte) type); - - switch (type) - { - case 1: - { - data.add(this.dyeID); - data.add(this.canReceive); - data.add(this.attackEntities); - data.add(this.linked != null); - NBTTagCompound nbt = new NBTTagCompound(); - getMultiBlock().save(nbt); - data.add(nbt); - break; - } - case 2: - { - data.add(this.energy().getEnergy() > 0); - break; - } - } - - return data; - } - - @Override - public void read(ByteBuf data, EntityPlayer player, PacketType type) - { - try - { - switch (data.readByte()) - { - case 1: - this.dyeID = data.readInt(); - this.canReceive = data.readBoolean(); - this.attackEntities = data.readBoolean(); - this.isLinkedClient = data.readBoolean(); - getMultiBlock().load(ByteBufUtils.readTag(data)); - break; - case 2: - this.isTransfering = data.readBoolean(); - break; - case 3: - this.doTransfer = true; - } - } - catch (Exception e) - { - e.printStackTrace(); - } - } - - @Override - public double teslaTransfer(double transferEnergy, boolean doTransfer) - { - if (getMultiBlock().isPrimary()) - { - if (doTransfer) - { - this.energy().receiveEnergy(transferEnergy, true); - - if (this.energy().didEnergyStateChange()) - { - this.sendPacket(2); - } - } - - return transferEnergy; - } - else - { - if (this.energy().getEnergy() > 0) - { - transferEnergy += this.energy().getEnergy(); - this.energy().setEnergy(0); - } - - return getMultiBlock().get().teslaTransfer(transferEnergy, doTransfer); - } - } - - public int getRange() - { - return Math.min(4 * (this.getHeight() - 1), 50); - } - - public void updatePositionStatus() - { - TileTesla mainTile = getLowestTesla(); - mainTile.getMultiBlock().deconstruct(); - mainTile.getMultiBlock().construct(); - - boolean isTop = new Vector3(this).add(new Vector3(0, 1, 0)).getTileEntity(this.worldObj) instanceof TileTesla; - boolean isBottom = new Vector3(this).add(new Vector3(0, -1, 0)).getTileEntity(this.worldObj) instanceof TileTesla; - - if (isTop && isBottom) - { - this.worldObj.setBlockMetadataWithNotify(this.xCoord, this.yCoord, this.zCoord, 1, 3); - } - else if (isBottom) - { - this.worldObj.setBlockMetadataWithNotify(this.xCoord, this.yCoord, this.zCoord, 2, 3); - } - else - { - this.worldObj.setBlockMetadataWithNotify(this.xCoord, this.yCoord, this.zCoord, 0, 3); - } - } - - /** - * Called only on bottom. - * - * @return The highest Tesla coil in this tower. - */ - public TileTesla getTopTelsa() - { - if (this.topCache != null) - { - return this.topCache; - } - - this.connectedTeslas.clear(); - Vector3 checkPosition = new Vector3(this); - TileTesla returnTile = this; - - while (true) - { - TileEntity t = checkPosition.getTileEntity(this.worldObj); - - if (t instanceof TileTesla) - { - this.connectedTeslas.add((TileTesla) t); - returnTile = (TileTesla) t; - } - else - { - break; - } - - checkPosition.add(0, 1, 0); - } - - this.topCache = returnTile; - return returnTile; - } - - /** - * Called only on bottom. - * - * @return The highest Tesla coil in this tower. - */ - public int getHeight() - { - this.connectedTeslas.clear(); - int y = 0; - - while (true) - { - TileEntity t = new Vector3(this).add(new Vector3(0, y, 0)).getTileEntity(this.worldObj); - - if (t instanceof TileTesla) - { - this.connectedTeslas.add((TileTesla) t); - y++; - } - else - { - break; - } - - } - - return y; - } - - @Override - public void invalidate() - { - TeslaGrid.instance().unregister(this); - super.invalidate(); - } - - public void setDye(int id) - { - this.dyeID = id; - this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); - } - - public boolean toggleReceive() - { - return this.canReceive = !this.canReceive; - } - - public boolean toggleEntityAttack() - { - boolean returnBool = this.attackEntities = !this.attackEntities; - this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); - return returnBool; - } - - /** - * Reads a tile entity from NBT. - */ - @Override - public void readFromNBT(NBTTagCompound nbt) - { - super.readFromNBT(nbt); - this.dyeID = nbt.getInteger("dyeID"); - this.canReceive = nbt.getBoolean("canReceive"); - this.attackEntities = nbt.getBoolean("attackEntities"); - - if (nbt.hasKey("link_x") && nbt.hasKey("link_y") && nbt.hasKey("link_z")) - { - this.linked = new Vector3(nbt.getInteger("link_x"), nbt.getInteger("link_y"), nbt.getInteger("link_z")); - this.linkDim = nbt.getInteger("linkDim"); - } - getMultiBlock().load(nbt); - } - - /** - * Writes a tile entity to NBT. - */ - @Override - public void writeToNBT(NBTTagCompound nbt) - { - super.writeToNBT(nbt); - nbt.setInteger("dyeID", this.dyeID); - nbt.setBoolean("canReceive", this.canReceive); - nbt.setBoolean("attackEntities", this.attackEntities); - - if (this.linked != null) - { - nbt.setInteger("link_x", (int) this.linked.x()); - nbt.setInteger("link_y", (int) this.linked.y()); - nbt.setInteger("link_z", (int) this.linked.z()); - nbt.setInteger("linkDim", this.linkDim); - } - getMultiBlock().save(nbt); - } - - public void setLink(Vector3 vector3, int dimID, boolean setOpponent) - { - if (!worldObj.isRemote) - { - World otherWorld = MinecraftServer.getServer().worldServerForDimension(linkDim); - - if (setOpponent && linked != null && otherWorld != null) - { - TileEntity tileEntity = linked.getTileEntity(otherWorld); - - if (tileEntity instanceof TileTesla) - { - ((TileTesla) tileEntity).setLink(null, this.linkDim, false); - } - } - - linked = vector3; - linkDim = dimID; - - worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); - - World newOtherWorld = MinecraftServer.getServer().worldServerForDimension(this.linkDim); - - if (setOpponent && newOtherWorld != null && this.linked != null) - { - TileEntity tileEntity = this.linked.getTileEntity(newOtherWorld); - - if (tileEntity instanceof TileTesla) - { - ((TileTesla) tileEntity).setLink(new Vector3(this), this.worldObj.provider.dimensionId, false); - } - } - } - } - - public boolean tryLink(VectorWorld vector) - { - if (vector != null) - { - if (vector.getTileEntity() instanceof TileTesla) - { - setLink(vector, vector.world().provider.dimensionId, true); - } - - return true; - } - - return false; - } - - - - @Override - public void onMultiBlockChanged() - { - - } - - @Override - public Iterable getMultiBlockVectors() - { - List vectors = new ArrayList(); - - Vector3 checkPosition = new Vector3(this); - - while (true) - { - TileEntity t = checkPosition.getTileEntity(this.worldObj); - - if (t instanceof TileTesla) - { - vectors.add(checkPosition.clone().subtract(getPosition())); - } - else - { - break; - } - - checkPosition.add(0, 1, 0); - } - - return vectors; - } - - public TileTesla getLowestTesla() - { - TileTesla lowest = this; - Vector3 checkPosition = new Vector3(this); - - while (true) - { - TileEntity t = checkPosition.getTileEntity(this.worldObj); - - if (t instanceof TileTesla) - { - lowest = (TileTesla) t; - } - else - { - break; - } - - checkPosition.add(0, -1, 0); - } - - return lowest; - } - - @Override - public World getWorld() - { - return worldObj; - } - - @Override - public Vector3 getPosition() - { - return new Vector3(this); - } - - @Override - public MultiBlockHandler getMultiBlock() - { - if (multiBlock == null) - multiBlock = new MultiBlockHandler(this); - - return multiBlock; - } - - @Override - public void setIO(ForgeDirection dir, int type) - { - if (getMultiBlock().isPrimary()) - { - super.setIO(dir, type); - } - else - { - getMultiBlock().get().setIO(dir, type); - } - } - - @Override - public int getIO(ForgeDirection dir) - { - if (getMultiBlock().isPrimary()) - { - return super.getIO(dir); - } - - return getMultiBlock().get().getIO(dir); - } - - @Override - public boolean use(EntityPlayer entityPlayer, int side, Vector3 hit) - { - if (entityPlayer.getCurrentEquippedItem() != null) - { - int dyeColor = ResonantUtil.isDye(entityPlayer.getCurrentEquippedItem()); - - if (dyeColor != -1) - { - getMultiBlock().get().setDye(dyeColor); - - if (!entityPlayer.capabilities.isCreativeMode) - { - entityPlayer.inventory.decrStackSize(entityPlayer.inventory.currentItem, 1); - } - - return true; - } - else if (entityPlayer.getCurrentEquippedItem().getItem() == Items.redstone) - { - boolean status = getMultiBlock().get().toggleEntityAttack(); - - if (!entityPlayer.capabilities.isCreativeMode) - { - entityPlayer.inventory.decrStackSize(entityPlayer.inventory.currentItem, 1); - } - - if (!world().isRemote) - { - entityPlayer.addChatMessage(new ChatComponentText(LanguageUtility.getLocal("message.tesla.toggleAttack").replace("%v", status + ""))); - } - - return true; - } - } - else - { - boolean receiveMode = getMultiBlock().get().toggleReceive(); - - if (!world().isRemote) - { - entityPlayer.addChatMessage(new ChatComponentText(LanguageUtility.getLocal("message.tesla.mode").replace("%v", receiveMode + ""))); - } - - return true; - - } - - return false; - } - - @Override - public boolean configure(EntityPlayer player, int side, Vector3 hit) - { - ItemStack itemStack = player.getCurrentEquippedItem(); - - if (player.isSneaking()) { - if (tryLink(LinkUtility.getLink(itemStack))) { - if (world().isRemote) - player.addChatMessage(new ChatComponentText("Successfully linked devices.")); - LinkUtility.clearLink(itemStack); - } else { - if (world().isRemote) - player.addChatMessage(new ChatComponentText("Marked link for device.")); - - LinkUtility.setLink(itemStack, new VectorWorld(this)); - } - - return true; - } - return super.configure(player, side, hit); - } - - @Override - public void onNeighborChanged(Block id) - { - updatePositionStatus(); - } -} diff --git a/src/main/scala/resonantinduction/electrical/tesla/TileTesla.scala b/src/main/scala/resonantinduction/electrical/tesla/TileTesla.scala new file mode 100644 index 000000000..4fe4542c3 --- /dev/null +++ b/src/main/scala/resonantinduction/electrical/tesla/TileTesla.scala @@ -0,0 +1,655 @@ +/** + * + */ +package resonantinduction.electrical.tesla + +import java.util.{ArrayList, Comparator, HashSet, List, PriorityQueue, Set} + +import cpw.mods.fml.common.network.ByteBufUtils +import io.netty.buffer.ByteBuf +import net.minecraft.block.Block +import net.minecraft.block.material.Material +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.init.Items +import net.minecraft.item.ItemStack +import net.minecraft.nbt.NBTTagCompound +import net.minecraft.server.MinecraftServer +import net.minecraft.tileentity.TileEntity +import net.minecraft.util.ChatComponentText +import net.minecraft.world.World +import net.minecraftforge.common.util.ForgeDirection +import resonant.lib.content.prefab.java.TileElectric +import resonant.lib.multiblock.reference.{IMultiBlockStructure, MultiBlockHandler} +import resonant.lib.network.discriminator.{PacketTile, PacketType} +import resonant.lib.network.handle.IPacketReceiver +import resonant.lib.render.EnumColor +import resonant.lib.utility.{LanguageUtility, LinkUtility} +import resonantinduction.core.util.ResonantUtil +import resonantinduction.core.{Reference, Settings} +import resonantinduction.electrical.Electrical +import universalelectricity.core.transform.vector.{Vector3, VectorWorld} +import scala.collection.JavaConversions._ + +/** + * The Tesla TileEntity. + * + * - Redstone (Prevent Output Toggle) - Right click (Prevent Input Toggle) + * + * @author Calclavia + * + */ +object TileTesla +{ + final val DEFAULT_COLOR: Int = 12 +} + +class TileTesla extends TileElectric(Material.iron) with IMultiBlockStructure[TileTesla] with ITesla with IPacketReceiver +{ + + final val TRANSFER_CAP: Double = 10000D + var dyeID: Int = TileTesla.DEFAULT_COLOR + var canReceive: Boolean = true + var attackEntities: Boolean = true + /** Client side to do sparks */ + var doTransfer: Boolean = true + /** Prevents transfer loops */ + final val outputBlacklist: Set[TileTesla] = new HashSet[TileTesla] + final val connectedTeslas: Set[TileTesla] = new HashSet[TileTesla] + /** + * Multiblock Methods. + */ + private var multiBlock: MultiBlockHandler[TileTesla] = null + /** + * Quantum Tesla + */ + var linked: Vector3 = null + var linkDim: Int = 0 + /** + * Client + */ + var zapCounter: Int = 0 + var isLinkedClient: Boolean = false + var isTransfering: Boolean = false + var topCache: TileTesla = null + + //Constructor + setCapacity(TRANSFER_CAP * 2) + setMaxTransfer(TRANSFER_CAP) + setTextureName(Reference.prefix + "material_metal_side") + normalRender(false) + isOpaqueCube(false) + + override def start + { + super.start + TeslaGrid.instance.register(this) + } + + override def update + { + super.update + if (this.getMultiBlock.isPrimary) + { + if (this.ticks % (4 + this.worldObj.rand.nextInt(2)) == 0 && ((this.worldObj.isRemote && isTransfering) || (!this.energy.isEmpty && !this.worldObj.isBlockIndirectlyGettingPowered(this.xCoord, this.yCoord, this.zCoord)))) + { + val topTesla: TileTesla = this.getTopTelsa + val topTeslaVector: Vector3 = new Vector3(topTesla) + if (this.linked != null || this.isLinkedClient) + { + if (!this.worldObj.isRemote) + { + val dimWorld: World = MinecraftServer.getServer.worldServerForDimension(this.linkDim) + if (dimWorld != null) + { + val transferTile: TileEntity = this.linked.getTileEntity(dimWorld) + if (transferTile.isInstanceOf[TileTesla] && !transferTile.isInvalid) + { + this.transfer((transferTile.asInstanceOf[TileTesla]), Math.min(energy.getEnergy, TRANSFER_CAP)) + if (this.zapCounter % 5 == 0 && Settings.SOUND_FXS) + { + this.worldObj.playSoundEffect(this.xCoord + 0.5, this.yCoord + 0.5, this.zCoord + 0.5, Reference.prefix + "electricshock", this.energy.getEnergy.asInstanceOf[Float] / TRANSFER_CAP.asInstanceOf[Float], 1.3f - 0.5f * (this.dyeID / 16f)) + } + } + } + } + else + { + Electrical.proxy.renderElectricShock(this.worldObj, topTeslaVector.clone.add(0.5), topTeslaVector.clone.add(new Vector3(0.5, java.lang.Double.POSITIVE_INFINITY, 0.5)), false) + } + } + else + { + val teslaToTransfer: PriorityQueue[ITesla] = new PriorityQueue[ITesla](1024, new Comparator[ITesla] + { + def compare(o1: ITesla, o2: ITesla): Int = + { + val distance1: Double = new Vector3(topTesla).distance(new Vector3(o1.asInstanceOf[TileEntity])) + val distance2: Double = new Vector3(topTesla).distance(new Vector3(o2.asInstanceOf[TileEntity])) + if (distance1 < distance2) + { + return 1 + } + else if (distance1 > distance2) + { + return -1 + } + return 0 + } + }) + + for (o <- TeslaGrid.instance.get) + { + var otherTesla = o + if (new Vector3(otherTesla.asInstanceOf[TileEntity]).distance(new Vector3(this)) < this.getRange && otherTesla != this) + { + if (otherTesla.isInstanceOf[TileTesla]) + { + otherTesla = (otherTesla.asInstanceOf[TileTesla]).getMultiBlock.get + } + if (!connectedTeslas.contains(otherTesla) && otherTesla != this && otherTesla.canTeslaTransfer(this) && canTeslaTransfer(otherTesla.asInstanceOf[TileEntity])) + { + teslaToTransfer.add(otherTesla) + } + } + } + if (teslaToTransfer.size > 0) + { + val transferEnergy: Double = this.energy.getEnergy / teslaToTransfer.size + val sentPacket: Boolean = false + + for (count <- 0 to 10) + { + if (!teslaToTransfer.isEmpty) + { + val tesla: ITesla = teslaToTransfer.poll + if (this.zapCounter % 5 == 0 && Settings.SOUND_FXS) + { + this.worldObj.playSoundEffect(this.xCoord + 0.5, this.yCoord + 0.5, this.zCoord + 0.5, Reference.prefix + "electricshock", this.energy.getEnergy.asInstanceOf[Float] / TRANSFER_CAP.asInstanceOf[Float], 1.3f - 0.5f * (this.dyeID / 16f)) + } + var targetVector: Vector3 = new Vector3(tesla.asInstanceOf[TileEntity]) + var heightRange: Int = 1 + if (tesla.isInstanceOf[TileTesla]) + { + getMultiBlock.get.outputBlacklist.add(this) + targetVector = new Vector3((tesla.asInstanceOf[TileTesla]).getTopTelsa) + heightRange = (tesla.asInstanceOf[TileTesla]).getHeight + } + val distance: Double = topTeslaVector.distance(targetVector) + Electrical.proxy.renderElectricShock(this.worldObj, new Vector3(topTesla).add(new Vector3(0.5)), targetVector.add(new Vector3(0.5, Math.random * heightRange / 3 - heightRange / 3, 0.5)), EnumColor.DYES(this.dyeID).toColor) + this.transfer(tesla, Math.min(transferEnergy, TRANSFER_CAP)) + if (!sentPacket && transferEnergy > 0) + { + this.sendPacket(3) + } + } + } + + } + } + this.zapCounter += 1 + this.outputBlacklist.clear + this.doTransfer = false + } + if (!this.worldObj.isRemote && this.energy.didEnergyStateChange) + { + this.sendPacket(2) + } + } + this.topCache = null + } + + private def transfer(tesla: ITesla, transferEnergy: Double) + { + if (transferEnergy > 0) + { + tesla.teslaTransfer(transferEnergy, true) + this.teslaTransfer(-transferEnergy, true) + } + } + + def canTeslaTransfer(tileEntity: TileEntity): Boolean = + { + if (tileEntity.isInstanceOf[TileTesla]) + { + val otherTesla: TileTesla = tileEntity.asInstanceOf[TileTesla] + if (!(otherTesla.getDye == dyeID || (otherTesla.getDye == TileTesla.DEFAULT_COLOR || dyeID == TileTesla.DEFAULT_COLOR))) + { + return false + } + } + return canReceive && tileEntity != getMultiBlock.get && !this.outputBlacklist.contains(tileEntity) + } + + def sendPacket(`type`: Int) + { + sendPacket(new PacketTile(this, this.getPacketData(`type`).toArray)) + } + + override def getDescPacket: PacketTile = + { + return new PacketTile(this, this.getPacketData(1).toArray) + } + + /** + * 1 - Description Packet + * 2 - Energy Update + * 3 - Tesla Beam + */ + def getPacketData(`type`: Int): ArrayList[Any] = + { + val data: ArrayList[Any] = new ArrayList[Any] + data.add(`type`.asInstanceOf[Byte]) + if (`type` == 1) + { + data.add(this.dyeID) + data.add(this.canReceive) + data.add(this.attackEntities) + data.add(this.linked != null) + val nbt: NBTTagCompound = new NBTTagCompound + getMultiBlock.save(nbt) + data.add(nbt) + } + if (`type` == 2) + { + data.add(this.energy.getEnergy > 0) + } + return data + } + + def read(data: ByteBuf, player: EntityPlayer, `type`: PacketType) + { + try + { + var id: Int = data.readByte + if (id == 1) + { + this.dyeID = data.readInt + this.canReceive = data.readBoolean + this.attackEntities = data.readBoolean + this.isLinkedClient = data.readBoolean + getMultiBlock.load(ByteBufUtils.readTag(data)) + } + if (id == 2) + { + this.isTransfering = data.readBoolean + } + if (id == 3) + { + this.doTransfer = true + } + } + catch + { + case e: Exception => + { + e.printStackTrace + } + } + } + + def teslaTransfer(e: Double, doTransfer: Boolean): Double = + { + var transferEnergy = e + if (getMultiBlock.isPrimary) + { + if (doTransfer) + { + this.energy.receiveEnergy(transferEnergy, true) + if (this.energy.didEnergyStateChange) + { + this.sendPacket(2) + } + } + return transferEnergy + } + else + { + if (this.energy.getEnergy > 0) + { + transferEnergy += this.energy.getEnergy + this.energy.setEnergy(0) + } + return getMultiBlock.get.teslaTransfer(transferEnergy, doTransfer) + } + } + + def getRange: Int = + { + return Math.min(4 * (this.getHeight - 1), 50) + } + + def updatePositionStatus + { + val mainTile: TileTesla = getLowestTesla + mainTile.getMultiBlock.deconstruct + mainTile.getMultiBlock.construct + val isTop: Boolean = new Vector3(this).add(new Vector3(0, 1, 0)).getTileEntity(this.worldObj).isInstanceOf[TileTesla] + val isBottom: Boolean = new Vector3(this).add(new Vector3(0, -1, 0)).getTileEntity(this.worldObj).isInstanceOf[TileTesla] + if (isTop && isBottom) + { + this.worldObj.setBlockMetadataWithNotify(this.xCoord, this.yCoord, this.zCoord, 1, 3) + } + else if (isBottom) + { + this.worldObj.setBlockMetadataWithNotify(this.xCoord, this.yCoord, this.zCoord, 2, 3) + } + else + { + this.worldObj.setBlockMetadataWithNotify(this.xCoord, this.yCoord, this.zCoord, 0, 3) + } + } + + /** + * Called only on bottom. + * + * @return The highest Tesla coil in this tower. + */ + def getTopTelsa: TileTesla = + { + if (this.topCache != null) + { + return this.topCache + } + this.connectedTeslas.clear + val checkPosition: Vector3 = new Vector3(this) + var returnTile: TileTesla = this + var exit = false + while (exit) + { + val t: TileEntity = checkPosition.getTileEntity(this.worldObj) + if (t.isInstanceOf[TileTesla]) + { + this.connectedTeslas.add(t.asInstanceOf[TileTesla]) + returnTile = t.asInstanceOf[TileTesla] + checkPosition.add(0, 1, 0) + } + else + { + exit = true + } + } + this.topCache = returnTile + return returnTile + } + + /** Gets color of the link */ + def getDye: Int = dyeID + + /** + * Called only on bottom. + * + * @return The highest Tesla coil in this tower. + */ + def getHeight: Int = + { + this.connectedTeslas.clear + var y: Int = 0 + var exit = false + while (!exit) + { + val t: TileEntity = new Vector3(this).add(new Vector3(0, y, 0)).getTileEntity(this.worldObj) + if (t.isInstanceOf[TileTesla]) + { + this.connectedTeslas.add(t.asInstanceOf[TileTesla]) + y += 1 + } + else + { + exit = true + } + } + return y + } + + override def invalidate + { + TeslaGrid.instance.unregister(this) + super.invalidate + } + + def setDye(id: Int) + { + this.dyeID = id + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord) + } + + def toggleReceive: Boolean = + { + this.canReceive = !this.canReceive + return canReceive + } + + def toggleEntityAttack: Boolean = + { + this.attackEntities = !this.attackEntities + val returnBool: Boolean = attackEntities + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord) + return returnBool + } + + /** + * Reads a tile entity from NBT. + */ + override def readFromNBT(nbt: NBTTagCompound) + { + super.readFromNBT(nbt) + this.dyeID = nbt.getInteger("dyeID") + this.canReceive = nbt.getBoolean("canReceive") + this.attackEntities = nbt.getBoolean("attackEntities") + if (nbt.hasKey("link_x") && nbt.hasKey("link_y") && nbt.hasKey("link_z")) + { + this.linked = new Vector3(nbt.getInteger("link_x"), nbt.getInteger("link_y"), nbt.getInteger("link_z")) + this.linkDim = nbt.getInteger("linkDim") + } + getMultiBlock.load(nbt) + } + + /** + * Writes a tile entity to NBT. + */ + override def writeToNBT(nbt: NBTTagCompound) + { + super.writeToNBT(nbt) + nbt.setInteger("dyeID", this.dyeID) + nbt.setBoolean("canReceive", this.canReceive) + nbt.setBoolean("attackEntities", this.attackEntities) + if (this.linked != null) + { + nbt.setInteger("link_x", this.linked.x.asInstanceOf[Int]) + nbt.setInteger("link_y", this.linked.y.asInstanceOf[Int]) + nbt.setInteger("link_z", this.linked.z.asInstanceOf[Int]) + nbt.setInteger("linkDim", this.linkDim) + } + getMultiBlock.save(nbt) + } + + def setLink(vector3: Vector3, dimID: Int, setOpponent: Boolean) + { + if (!worldObj.isRemote) + { + val otherWorld: World = MinecraftServer.getServer.worldServerForDimension(linkDim) + if (setOpponent && linked != null && otherWorld != null) + { + val tileEntity: TileEntity = linked.getTileEntity(otherWorld) + if (tileEntity.isInstanceOf[TileTesla]) + { + (tileEntity.asInstanceOf[TileTesla]).setLink(null, this.linkDim, false) + } + } + linked = vector3 + linkDim = dimID + worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord) + val newOtherWorld: World = MinecraftServer.getServer.worldServerForDimension(this.linkDim) + if (setOpponent && newOtherWorld != null && this.linked != null) + { + val tileEntity: TileEntity = this.linked.getTileEntity(newOtherWorld) + if (tileEntity.isInstanceOf[TileTesla]) + { + (tileEntity.asInstanceOf[TileTesla]).setLink(new Vector3(this), this.worldObj.provider.dimensionId, false) + } + } + } + } + + def tryLink(vector: VectorWorld): Boolean = + { + if (vector != null) + { + if (vector.getTileEntity.isInstanceOf[TileTesla]) + { + setLink(vector, vector.world.provider.dimensionId, true) + } + return true + } + return false + } + + def onMultiBlockChanged + { + } + + def getMultiBlockVectors: java.lang.Iterable[Vector3] = + { + val vectors: List[Vector3] = new ArrayList[Vector3] + val checkPosition: Vector3 = new Vector3(this) + var exit = false + while (!exit) + { + val t: TileEntity = checkPosition.getTileEntity(this.worldObj) + if (t.isInstanceOf[TileTesla]) + { + vectors.add(checkPosition.clone.subtract(getPosition)) + } + else + { + exit = true + } + checkPosition.add(0, 1, 0) + } + return vectors + } + + def getLowestTesla: TileTesla = + { + var lowest: TileTesla = this + val checkPosition: Vector3 = new Vector3(this) + var exit = false + while (!exit) + { + val t: TileEntity = checkPosition.getTileEntity(this.worldObj) + if (t.isInstanceOf[TileTesla]) + { + lowest = t.asInstanceOf[TileTesla] + } + else + { + exit = true + } + checkPosition.add(0, -1, 0) + } + return lowest + } + + def getWorld: World = + { + return worldObj + } + + def getPosition: Vector3 = + { + return new Vector3(this) + } + + def getMultiBlock: MultiBlockHandler[TileTesla] = + { + if (multiBlock == null) multiBlock = new MultiBlockHandler[TileTesla](this) + return multiBlock + } + + override def setIO(dir: ForgeDirection, `type`: Int) + { + if (getMultiBlock.isPrimary) + { + super.setIO(dir, `type`) + } + else + { + getMultiBlock.get.setIO(dir, `type`) + } + } + + override def getIO(dir: ForgeDirection): Int = + { + if (getMultiBlock.isPrimary) + { + return super.getIO(dir) + } + return getMultiBlock.get.getIO(dir) + } + + override def use(entityPlayer: EntityPlayer, side: Int, hit: Vector3): Boolean = + { + if (entityPlayer.getCurrentEquippedItem != null) + { + val dyeColor: Int = ResonantUtil.isDye(entityPlayer.getCurrentEquippedItem) + if (dyeColor != -1) + { + getMultiBlock.get.setDye(dyeColor) + if (!entityPlayer.capabilities.isCreativeMode) + { + entityPlayer.inventory.decrStackSize(entityPlayer.inventory.currentItem, 1) + } + return true + } + else if (entityPlayer.getCurrentEquippedItem.getItem eq Items.redstone) + { + val status: Boolean = getMultiBlock.get.toggleEntityAttack + if (!entityPlayer.capabilities.isCreativeMode) + { + entityPlayer.inventory.decrStackSize(entityPlayer.inventory.currentItem, 1) + } + if (!world.isRemote) + { + entityPlayer.addChatMessage(new ChatComponentText(LanguageUtility.getLocal("message.tesla.toggleAttack").replace("%v", status + ""))) + } + return true + } + } + else + { + val receiveMode: Boolean = getMultiBlock.get.toggleReceive + if (!world.isRemote) + { + entityPlayer.addChatMessage(new ChatComponentText(LanguageUtility.getLocal("message.tesla.mode").replace("%v", receiveMode + ""))) + } + return true + } + return false + } + + override def configure(player: EntityPlayer, side: Int, hit: Vector3): Boolean = + { + val itemStack: ItemStack = player.getCurrentEquippedItem + if (player.isSneaking) + { + if (tryLink(LinkUtility.getLink(itemStack))) + { + if (world.isRemote) player.addChatMessage(new ChatComponentText("Successfully linked devices.")) + LinkUtility.clearLink(itemStack) + } + else + { + if (world.isRemote) player.addChatMessage(new ChatComponentText("Marked link for device.")) + LinkUtility.setLink(itemStack, new VectorWorld(this)) + } + return true + } + return super.configure(player, side, hit) + } + + override def onNeighborChanged(id: Block) + { + updatePositionStatus + } + +} \ No newline at end of file