Converted Casting mold and Millstone to scala

This commit is contained in:
Robert S 2014-09-27 16:26:12 -04:00
parent afb718af8a
commit 5b49483427
10 changed files with 1039 additions and 1211 deletions

View file

@ -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, "");
}
}
}
}

View file

@ -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, "")
}
}
}
}

View file

@ -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, "");
}
}
}

View file

@ -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, "")
}
}
}

View file

@ -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.
* <p/>
* 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;
}
}

View file

@ -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.
* <p/>
* 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
}
}

View file

@ -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;
}
}

View file

@ -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
}
}

View file

@ -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<TileTesla>, 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<TileTesla> outputBlacklist = new HashSet<TileTesla>();
private final Set<TileTesla> connectedTeslas = new HashSet<TileTesla>();
/**
* Multiblock Methods.
*/
private MultiBlockHandler<TileTesla> 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<ITesla> teslaToTransfer = new PriorityQueue<ITesla>(1024, new Comparator<ITesla>()
{
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<Vector3> getMultiBlockVectors()
{
List<Vector3> vectors = new ArrayList<Vector3>();
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<TileTesla> getMultiBlock()
{
if (multiBlock == null)
multiBlock = new MultiBlockHandler<TileTesla>(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();
}
}

View file

@ -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
}
}