diff --git a/src/resonantinduction/ITesla.java b/src/resonantinduction/ITesla.java index 4678c222..563e1be9 100644 --- a/src/resonantinduction/ITesla.java +++ b/src/resonantinduction/ITesla.java @@ -3,6 +3,8 @@ */ package resonantinduction; +import net.minecraft.tileentity.TileEntity; + /** * @author Calclavia * @@ -11,4 +13,6 @@ public interface ITesla { public void transfer(float transferEnergy); + public boolean canReceive(TileEntity tileEntity); + } diff --git a/src/resonantinduction/base/Vector3.java b/src/resonantinduction/base/Vector3.java index 9762d1cd..cb6d7386 100644 --- a/src/resonantinduction/base/Vector3.java +++ b/src/resonantinduction/base/Vector3.java @@ -3,8 +3,14 @@ */ package resonantinduction.base; +import java.util.List; + import net.minecraft.entity.Entity; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.MathHelper; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.Vec3; import net.minecraft.world.World; /** @@ -129,6 +135,11 @@ public class Vector3 return new Vector3(this.x + offset.x, this.y + offset.y, this.z + offset.z); } + public Vector3 translate(int offset) + { + return new Vector3(this.x + offset, this.y + offset, this.z + offset); + } + public Vector3 normalize() { double d = getMagnitude(); @@ -191,13 +202,22 @@ public class Vector3 return axis.getRotationMatrix(angle); } - public static Vector3 getDeltaPositionFromRotation(float rotationYaw, float rotationPitch) + public static Vector3 getDeltaPositionFromRotation(double rotationYaw, double rotationPitch) { rotationYaw = rotationYaw + 90; rotationPitch = -rotationPitch; return new Vector3(Math.cos(Math.toRadians(rotationYaw)), Math.sin(Math.toRadians(rotationPitch)), Math.sin(Math.toRadians(rotationYaw))); } + public double[] getDeltaRotationFromPosition() + { + double rotationPitch = Math.toDegrees(Math.asin(this.y)); + double rotationYaw = Math.toDegrees(Math.atan2(this.z, this.x)); + rotationYaw = rotationYaw - 90; + rotationPitch = -rotationPitch; + return new double[] { MathHelper.wrapAngleTo180_double(rotationYaw), MathHelper.wrapAngleTo180_double(rotationPitch) }; + } + public double getAngle(Vector3 vector) { return this.getAnglePreNorm(vector.clone().normalize()); @@ -213,6 +233,67 @@ public class Vector3 return world.getBlockTileEntity((int) this.x, (int) this.y, (int) this.z); } + public MovingObjectPosition rayTraceEntities(World world, double rotationYaw, double rotationPitch, double reachDistance) + { + MovingObjectPosition pickedEntity = null; + Vec3 startingPosition = this.toVec3(); + Vec3 look = getDeltaPositionFromRotation(rotationYaw, rotationPitch).toVec3(); + Vec3 reachPoint = Vec3.createVectorHelper(startingPosition.xCoord + look.xCoord * reachDistance, startingPosition.yCoord + look.yCoord * reachDistance, startingPosition.zCoord + look.zCoord * reachDistance); + + double checkBorder = 1.1 * reachDistance; + AxisAlignedBB boxToScan = AxisAlignedBB.getAABBPool().getAABB(-checkBorder, -checkBorder, -checkBorder, checkBorder, checkBorder, checkBorder).offset(this.x, this.y, this.z);; + + @SuppressWarnings("unchecked") + List entitiesHit = world.getEntitiesWithinAABBExcludingEntity(null, boxToScan); + double closestEntity = reachDistance; + if (entitiesHit == null || entitiesHit.isEmpty()) + { + return null; + } + for (Entity entityHit : entitiesHit) + { + if (entityHit != null && entityHit.canBeCollidedWith() && entityHit.boundingBox != null) + { + float border = entityHit.getCollisionBorderSize(); + AxisAlignedBB aabb = entityHit.boundingBox.expand(border, border, border); + MovingObjectPosition hitMOP = aabb.calculateIntercept(startingPosition, reachPoint); + + if (hitMOP != null) + { + if (aabb.isVecInside(startingPosition)) + { + if (0.0D < closestEntity || closestEntity == 0.0D) + { + pickedEntity = new MovingObjectPosition(entityHit); + if (pickedEntity != null) + { + pickedEntity.hitVec = hitMOP.hitVec; + closestEntity = 0.0D; + } + } + } + else + { + double distance = startingPosition.distanceTo(hitMOP.hitVec); + + if (distance < closestEntity || closestEntity == 0.0D) + { + pickedEntity = new MovingObjectPosition(entityHit); + pickedEntity.hitVec = hitMOP.hitVec; + closestEntity = distance; + } + } + } + } + } + return pickedEntity; + } + + private Vec3 toVec3() + { + return Vec3.createVectorHelper(this.x, this.y, this.z); + } + @Override public Vector3 clone() { diff --git a/src/resonantinduction/fx/FXElectricBolt.java b/src/resonantinduction/fx/FXElectricBolt.java index 9792061d..0a6e1638 100644 --- a/src/resonantinduction/fx/FXElectricBolt.java +++ b/src/resonantinduction/fx/FXElectricBolt.java @@ -1,5 +1,13 @@ package resonantinduction.fx; +import static org.lwjgl.opengl.GL11.GL_BLEND; +import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA; +import static org.lwjgl.opengl.GL11.GL_SMOOTH; +import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA; +import static org.lwjgl.opengl.GL11.glBlendFunc; +import static org.lwjgl.opengl.GL11.glEnable; +import static org.lwjgl.opengl.GL11.glShadeModel; + import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -271,6 +279,10 @@ public class FXElectricBolt extends EntityFX GL11.glDepthMask(false); GL11.glEnable(3042); + glShadeModel(GL_SMOOTH); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + FMLClientHandler.instance().getClient().renderEngine.func_110577_a(TEXTURE); /** * Render the actual bolts. @@ -278,7 +290,6 @@ public class FXElectricBolt extends EntityFX tessellator.startDrawingQuads(); tessellator.setBrightness(15728880); Vector3 playerVector = new Vector3(sinYaw * -cosPitch, -cosSinPitch / cosYaw, cosYaw * cosPitch); - float voltage = this.particleAge >= 0 ? ((float) this.particleAge / (float) this.particleMaxAge) : 0.0F; int renderlength = (int) ((this.particleAge + partialframe + (int) (this.boltLength * 3.0F)) / (int) (this.boltLength * 3.0F) * this.segmentCount); @@ -302,7 +313,7 @@ public class FXElectricBolt extends EntityFX float ry2 = (float) (endVec.y - interpPosY); float rz2 = (float) (endVec.z - interpPosZ); - tessellator.setColorRGBA_F(this.particleRed, this.particleGreen, this.particleBlue, (1.0F - voltage * 0.5f) * segment.alpha); + tessellator.setColorRGBA_F(this.particleRed, this.particleGreen, this.particleBlue, (1.0F - (this.particleAge >= 0 ? ((float) this.particleAge / (float) this.particleMaxAge) : 0.0F) * 0.6f) * segment.alpha); tessellator.addVertexWithUV(rx2 - diffNext.x, ry2 - diffNext.y, rz2 - diffNext.z, 0.5D, 0.0D); tessellator.addVertexWithUV(rx1 - diffPrev.x, ry1 - diffPrev.y, rz1 - diffPrev.z, 0.5D, 0.0D); tessellator.addVertexWithUV(rx1 + diffPrev.x, ry1 + diffPrev.y, rz1 + diffPrev.z, 0.5D, 1.0D); @@ -350,7 +361,7 @@ public class FXElectricBolt extends EntityFX tessellator.startDrawingQuads(); } - public class BoltPoint extends Vector3 + private class BoltPoint extends Vector3 { public Vector3 base; public Vector3 offset; @@ -368,7 +379,7 @@ public class FXElectricBolt extends EntityFX } } - public class BoltSegment + private class BoltSegment { public BoltPoint start; public BoltPoint end; diff --git a/src/resonantinduction/tesla/BlockTesla.java b/src/resonantinduction/tesla/BlockTesla.java index c7003531..6a687c6b 100644 --- a/src/resonantinduction/tesla/BlockTesla.java +++ b/src/resonantinduction/tesla/BlockTesla.java @@ -38,16 +38,42 @@ public class BlockTesla extends BlockBase implements ITileEntityProvider @Override public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer entityPlayer, int par6, float par7, float par8, float par9) { - TileEntity tileEntity = world.getBlockTileEntity(x, y, z); - tileEntity = ((TileEntityTesla) tileEntity).getControllingTelsa(); + TileEntity t = world.getBlockTileEntity(x, y, z); + TileEntityTesla tileEntity = ((TileEntityTesla) t).getControllingTelsa(); if (entityPlayer.getCurrentEquippedItem() != null) { if (entityPlayer.getCurrentEquippedItem().itemID == Item.dyePowder.itemID) { - ((TileEntityTesla) tileEntity).setDye(entityPlayer.getCurrentEquippedItem().getItemDamage()); + tileEntity.setDye(entityPlayer.getCurrentEquippedItem().getItemDamage()); + + if (!entityPlayer.capabilities.isCreativeMode) + { + entityPlayer.inventory.decrStackSize(entityPlayer.inventory.currentItem, 1); + } return true; } + else if (entityPlayer.getCurrentEquippedItem().itemID == Item.redstone.itemID) + { + tileEntity.toggleEntityAttack(); + + if (!entityPlayer.capabilities.isCreativeMode) + { + entityPlayer.inventory.decrStackSize(entityPlayer.inventory.currentItem, 1); + } + return true; + } + } + else + { + boolean receiveMode = tileEntity.toggleReceive(); + + if (world.isRemote) + { + entityPlayer.addChatMessage("Tesla receive mode is now " + receiveMode); + } + return true; + } return false; diff --git a/src/resonantinduction/tesla/TileEntityTesla.java b/src/resonantinduction/tesla/TileEntityTesla.java index f7dfbb95..f1fa0c9e 100644 --- a/src/resonantinduction/tesla/TileEntityTesla.java +++ b/src/resonantinduction/tesla/TileEntityTesla.java @@ -4,15 +4,22 @@ package resonantinduction.tesla; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.HashSet; +import java.util.List; import java.util.Set; import net.minecraft.block.BlockFurnace; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.item.crafting.FurnaceRecipes; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.packet.Packet; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityFurnace; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.DamageSource; +import net.minecraft.util.MovingObjectPosition; import resonantinduction.ITesla; import resonantinduction.PacketHandler; import resonantinduction.ResonantInduction; @@ -23,19 +30,39 @@ import resonantinduction.base.Vector3; import com.google.common.io.ByteArrayDataInput; /** + * The Tesla TileEntity. + * + * - Redstone (Prevent Output Toggle) - Right click (Prevent Input Toggle) + * * @author Calclavia * */ public class TileEntityTesla extends TileEntityBase implements ITesla, IPacketReceiver { - public static final Vector3[] dyeColors = new Vector3[] { new Vector3(), new Vector3(1, 0, 0), new Vector3(0, 1, 0), new Vector3(0.5, 0.5, 0), new Vector3(0, 0, 1), new Vector3(0.5, 0, 05), new Vector3(0, 0.3, 1), new Vector3(0.8, 0.8, 0.8), new Vector3(0.3, 0.3, 0.3), new Vector3(0.7, 0.2, 0.2), new Vector3(0.1, 0.872, 0.884), new Vector3(0, 0.8, 0.8), new Vector3(0.46f, 0.932, 1), new Vector3(0.5, 0.2, 0.5), new Vector3(0.7, 0.5, 0.1), new Vector3(1, 1, 1) }; - private int dyeID = 12; + private final int DEFAULT_COLOR = 12; + private int dyeID = DEFAULT_COLOR; private float energy = 0; private boolean doTransfer = false; - private Set connectedTeslas = new HashSet(); + private boolean canReceive = true; + private boolean attackEntities = true; + + /** Prevents transfer loops */ + private final Set outputBlacklist = new HashSet(); + private final Set connectedTeslas = new HashSet(); + + /** + * Caching + */ + private TileEntityTesla topCache = null; + private TileEntityTesla controlCache = null; + + /** + * Client + */ + private int zapCounter = 0; @Override public void initiate() @@ -53,133 +80,199 @@ public class TileEntityTesla extends TileEntityBase implements ITesla, IPacketRe /** * Only transfer if it is the bottom controlling Tesla tower. */ - // TODO: Fix client side issue. || this.worldObj.isRemote - if (this.ticks % 2 == 0 && this.isController() && ((this.getEnergyStored() > 0 && this.doTransfer) || this.worldObj.isRemote) && !this.worldObj.isBlockIndirectlyGettingPowered(this.xCoord, this.yCoord, this.zCoord)) + if (this.isController()) { - Set transferTeslaCoils = new HashSet(); - - for (ITesla tesla : TeslaGrid.instance().get()) + // TODO: Fix client side issue. || this.worldObj.isRemote + if (this.ticks % (5 + this.worldObj.rand.nextInt(2)) == 0 && ((this.getEnergyStored() > 0 && this.doTransfer) || this.worldObj.isRemote) && !this.worldObj.isBlockIndirectlyGettingPowered(this.xCoord, this.yCoord, this.zCoord)) { - if (new Vector3((TileEntity) tesla).distance(new Vector3(this)) < this.getRange()) + List transferTeslaCoils = new ArrayList(); + + for (ITesla tesla : TeslaGrid.instance().get()) { - if (!this.connectedTeslas.contains(tesla)) + if (new Vector3((TileEntity) tesla).distance(new Vector3(this)) < this.getRange()) { - if (tesla instanceof TileEntityTesla) + /** + * Make sure Tesla is not part of this tower. + */ + if (!this.connectedTeslas.contains(tesla) && tesla.canReceive(this)) { - tesla = ((TileEntityTesla) tesla).getControllingTelsa(); + if (tesla instanceof TileEntityTesla) + { + if (((TileEntityTesla) tesla).getHeight() <= 1) + { + continue; + } + + tesla = ((TileEntityTesla) tesla).getControllingTelsa(); + } + + transferTeslaCoils.add(tesla); + } + } + } + + final TileEntityTesla topTesla = this.getTopTelsa(); + final Vector3 topTeslaVector = new Vector3(topTesla); + /** + * Sort by distance. + */ + Collections.sort(transferTeslaCoils, 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; } - transferTeslaCoils.add(tesla); + return 0; + } + + @Override + public int compare(Object obj, Object obj1) + { + return compare((ITesla) obj, (ITesla) obj1); + } + }); + + if (transferTeslaCoils.size() > 0) + { + float transferEnergy = this.getEnergyStored() / transferTeslaCoils.size(); + int count = 0; + for (ITesla tesla : transferTeslaCoils) + { + if (this.zapCounter % 5 == 0) + { + this.worldObj.playSoundEffect(this.xCoord + 0.5, this.yCoord + 0.5, this.zCoord + 0.5, ResonantInduction.PREFIX + "electricshock", this.getEnergyStored() / 25, (float) (1.3f - 0.5f * ((float) this.dyeID / 16f))); + } + + Vector3 targetVector = new Vector3((TileEntity) tesla); + + if (tesla instanceof TileEntityTesla) + { + ((TileEntityTesla) tesla).getControllingTelsa().outputBlacklist.add(this); + targetVector = new Vector3(((TileEntityTesla) tesla).getTopTelsa()); + } + + double distance = topTeslaVector.distance(targetVector); + ResonantInduction.proxy.renderElectricShock(this.worldObj, new Vector3(topTesla).translate(new Vector3(0.5)), targetVector.translate(new Vector3(0.5)), (float) dyeColors[this.dyeID].x, (float) dyeColors[this.dyeID].y, (float) dyeColors[this.dyeID].z); + + tesla.transfer(transferEnergy * (1 - (this.worldObj.rand.nextFloat() * 0.1f))); + this.transfer(-transferEnergy); + + if (this.attackEntities && this.zapCounter % 5 == 0) + { + double[] rotations = topTeslaVector.difference(targetVector).normalize().getDeltaRotationFromPosition(); + MovingObjectPosition mop = topTeslaVector.rayTraceEntities(this.worldObj, rotations[0], rotations[1], distance); + // System.out.println(Vector3.getDeltaPositionFromRotation(rotations[0], + // rotations[1]) + " :" + mop); + + if (mop != null && mop.entityHit != null) + { + if (mop.entityHit instanceof EntityLivingBase) + { + mop.entityHit.attackEntityFrom(DamageSource.magic, 1); + ResonantInduction.proxy.renderElectricShock(this.worldObj, new Vector3(topTesla).translate(new Vector3(0.5)), new Vector3(mop.entityHit)); + } + } + } + + if (count++ > 1) + { + break; + } } } + + this.zapCounter++; + this.outputBlacklist.clear(); } - if (transferTeslaCoils.size() > 0) - { - float transferEnergy = this.getEnergyStored() / transferTeslaCoils.size(); + /** + * Draws power from furnace below it. + * + * @author Calclavia + */ + TileEntity tileEntity = this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord - 1, this.zCoord); - for (ITesla tesla : transferTeslaCoils) + if (tileEntity instanceof TileEntityFurnace) + { + TileEntityFurnace furnaceTile = (TileEntityFurnace) tileEntity; + + if (furnaceTile.getStackInSlot(0) == null) { - if (this.ticks % 20 == 0) + /** + * Steal power from furnace. + */ + boolean doBlockStateUpdate = furnaceTile.furnaceBurnTime > 0; + + if (furnaceTile.furnaceBurnTime == 0) { - this.worldObj.playSoundEffect(this.xCoord + 0.5, this.yCoord + 0.5, this.zCoord + 0.5, ResonantInduction.PREFIX + "electricshock", this.getEnergyStored() / 10, (float) (1 - 0.2 * (this.dyeID / 16))); + int burnTime = TileEntityFurnace.getItemBurnTime(furnaceTile.getStackInSlot(1)); + + if (burnTime > 0) + { + furnaceTile.decrStackSize(1, 1); + furnaceTile.furnaceBurnTime = burnTime; + } + } + else + { + this.transfer(ResonantInduction.POWER_PER_COAL / 20); + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); } - Vector3 teslaVector = new Vector3((TileEntity) tesla); - - if (tesla instanceof TileEntityTesla) + if (doBlockStateUpdate != furnaceTile.furnaceBurnTime > 0) { - teslaVector = new Vector3(((TileEntityTesla) tesla).getControllingTelsa()); - } - - ResonantInduction.proxy.renderElectricShock(this.worldObj, new Vector3(this.getTopTelsa()).translate(new Vector3(0.5)), teslaVector.translate(new Vector3(0.5)), (float) dyeColors[this.dyeID].x, (float) dyeColors[this.dyeID].y, (float) dyeColors[this.dyeID].z); - - tesla.transfer(transferEnergy * (1 - (this.worldObj.rand.nextFloat() * 0.1f))); - this.transfer(-transferEnergy); - } - } - } - - /* - * int radius = 10; List entities = - * this.worldObj.getEntitiesWithinAABBExcludingEntity(null, - * AxisAlignedBB.getAABBPool().getAABB(this.xCoord - radius, this.yCoord - radius, - * this.zCoord - radius, this.xCoord + radius, this.yCoord + radius, this.zCoord + radius)); - * - * for (Entity entity : entities) { - * ResonantInduction.proxy.renderElectricShock(this.worldObj, new - * Vector3(this).translate(new Vector3(0.5)), new Vector3(entity)); } - */ - - /** - * Draws power from furnace below it. - * - * @author Calclavia - */ - TileEntity tileEntity = this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord - 1, this.zCoord); - - if (tileEntity instanceof TileEntityFurnace) - { - TileEntityFurnace furnaceTile = (TileEntityFurnace) tileEntity; - - if (furnaceTile.getStackInSlot(0) == null) - { - /** - * Steal power from furnace. - */ - boolean doBlockStateUpdate = furnaceTile.furnaceBurnTime > 0; - - if (furnaceTile.furnaceBurnTime == 0) - { - int burnTime = TileEntityFurnace.getItemBurnTime(furnaceTile.getStackInSlot(1)); - - if (burnTime > 0) - { - furnaceTile.decrStackSize(1, 1); - furnaceTile.furnaceBurnTime = burnTime; + BlockFurnace.updateFurnaceBlockState(furnaceTile.furnaceBurnTime > 0, furnaceTile.worldObj, furnaceTile.xCoord, furnaceTile.yCoord, furnaceTile.zCoord); } } - else + else if (this.getEnergyStored() > ResonantInduction.POWER_PER_COAL / 20 && furnaceTile.getStackInSlot(1) == null && FurnaceRecipes.smelting().getSmeltingResult(furnaceTile.getStackInSlot(0)) != null) { - this.transfer(ResonantInduction.POWER_PER_COAL / 20); + /** + * Inject power to furnace. + */ + boolean doBlockStateUpdate = furnaceTile.furnaceBurnTime > 0; + + furnaceTile.furnaceBurnTime += 2; + this.transfer(-ResonantInduction.POWER_PER_COAL / 20); this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); - } - if (doBlockStateUpdate != furnaceTile.furnaceBurnTime > 0) - { - BlockFurnace.updateFurnaceBlockState(furnaceTile.furnaceBurnTime > 0, furnaceTile.worldObj, furnaceTile.xCoord, furnaceTile.yCoord, furnaceTile.zCoord); + if (doBlockStateUpdate != furnaceTile.furnaceBurnTime > 0) + { + BlockFurnace.updateFurnaceBlockState(furnaceTile.furnaceBurnTime > 0, furnaceTile.worldObj, furnaceTile.xCoord, furnaceTile.yCoord, furnaceTile.zCoord); + } } } - else if (this.getEnergyStored() > ResonantInduction.POWER_PER_COAL / 20 && furnaceTile.getStackInSlot(1) == null && FurnaceRecipes.smelting().getSmeltingResult(furnaceTile.getStackInSlot(0)) != null) + + if (!this.worldObj.isRemote && this.getEnergyStored() > 0 != doPacketUpdate) { - /** - * Inject power to furnace. - */ - boolean doBlockStateUpdate = furnaceTile.furnaceBurnTime > 0; - - furnaceTile.furnaceBurnTime += 2; - this.transfer(-ResonantInduction.POWER_PER_COAL / 20); this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); - - if (doBlockStateUpdate != furnaceTile.furnaceBurnTime > 0) - { - BlockFurnace.updateFurnaceBlockState(furnaceTile.furnaceBurnTime > 0, furnaceTile.worldObj, furnaceTile.xCoord, furnaceTile.yCoord, furnaceTile.zCoord); - } } } - if (!this.worldObj.isRemote && this.getEnergyStored() > 0 != doPacketUpdate) - { - this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); - } + this.clearCache(); + } + + @Override + public boolean canReceive(TileEntity tileEntity) + { + return this.canReceive && !this.outputBlacklist.contains(tileEntity); } @Override public Packet getDescriptionPacket() { - return PacketHandler.getTileEntityPacket(this, (byte) 1, this.getEnergyStored(), this.dyeID); + return PacketHandler.getTileEntityPacket(this, (byte) 1, this.getEnergyStored(), this.dyeID, this.canReceive); } - + @Override public ArrayList getNetworkedData(ArrayList data) { @@ -196,6 +289,7 @@ public class TileEntityTesla extends TileEntityBase implements ITesla, IPacketRe case 1: this.energy = input.readFloat(); this.dyeID = input.readInt(); + this.canReceive = input.readBoolean(); break; } @@ -213,6 +307,12 @@ public class TileEntityTesla extends TileEntityBase implements ITesla, IPacketRe return this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord) == 0; } + private void clearCache() + { + this.topCache = null; + this.controlCache = null; + } + @Override public void transfer(float transferEnergy) { @@ -235,7 +335,7 @@ public class TileEntityTesla extends TileEntityBase implements ITesla, IPacketRe public int getRange() { - return 5 * (this.getHeight() - 1); + return Math.min(5 * (this.getHeight() - 1), 50); } public void updatePositionStatus() @@ -264,6 +364,11 @@ public class TileEntityTesla extends TileEntityBase implements ITesla, IPacketRe */ public TileEntityTesla getTopTelsa() { + if (this.topCache != null) + { + return this.topCache; + } + this.connectedTeslas.clear(); Vector3 checkPosition = new Vector3(this); TileEntityTesla returnTile = this; @@ -285,6 +390,7 @@ public class TileEntityTesla extends TileEntityBase implements ITesla, IPacketRe checkPosition.y++; } + this.topCache = returnTile; return returnTile; } @@ -295,6 +401,11 @@ public class TileEntityTesla extends TileEntityBase implements ITesla, IPacketRe */ public TileEntityTesla getControllingTelsa() { + if (this.controlCache != null) + { + return this.controlCache; + } + Vector3 checkPosition = new Vector3(this); TileEntityTesla returnTile = this; @@ -314,6 +425,7 @@ public class TileEntityTesla extends TileEntityBase implements ITesla, IPacketRe checkPosition.y--; } + this.controlCache = returnTile; return returnTile; } @@ -359,6 +471,16 @@ public class TileEntityTesla extends TileEntityBase implements ITesla, IPacketRe this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); } + public boolean toggleReceive() + { + return this.canReceive = !this.canReceive; + } + + public boolean toggleEntityAttack() + { + return this.attackEntities = !this.attackEntities; + } + /** * Reads a tile entity from NBT. */ @@ -366,6 +488,8 @@ public class TileEntityTesla extends TileEntityBase implements ITesla, IPacketRe { super.readFromNBT(nbt); this.dyeID = nbt.getInteger("dyeID"); + this.canReceive = nbt.getBoolean("canReceive"); + this.attackEntities = nbt.getBoolean("attackEntities"); } /** @@ -375,5 +499,8 @@ public class TileEntityTesla extends TileEntityBase implements ITesla, IPacketRe { super.writeToNBT(nbt); nbt.setInteger("dyeID", this.dyeID); + nbt.setBoolean("canReceive", this.canReceive); + nbt.setBoolean("attackEntities", this.attackEntities); } + }