Java tutorial
package micdoodle8.mods.galacticraft.core.tile; import java.util.EnumSet; import java.util.HashSet; import micdoodle8.mods.galacticraft.api.tile.IDisableableMachine; import micdoodle8.mods.galacticraft.api.transmission.core.item.IItemElectric; import micdoodle8.mods.galacticraft.api.vector.Vector3; import micdoodle8.mods.galacticraft.api.world.IGalacticraftWorldProvider; import micdoodle8.mods.galacticraft.api.world.ISolarLevel; import micdoodle8.mods.galacticraft.core.GalacticraftCore; import micdoodle8.mods.galacticraft.core.blocks.GCCoreBlockMulti; import micdoodle8.mods.galacticraft.core.blocks.GCCoreBlockSolar; import micdoodle8.mods.galacticraft.core.blocks.GCCoreBlocks; import micdoodle8.mods.galacticraft.core.network.GCCorePacketManager; import micdoodle8.mods.galacticraft.core.network.IPacketReceiver; import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.network.INetworkManager; import net.minecraft.network.packet.Packet; import net.minecraft.network.packet.Packet250CustomPayload; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.StatCollector; import net.minecraftforge.common.ForgeDirection; import com.google.common.io.ByteArrayDataInput; import cpw.mods.fml.client.FMLClientHandler; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; /** * GCCoreTileEntitySolar.java * * This file is part of the Galacticraft project * * @author micdoodle8 * @license Lesser GNU Public License v3 (http://www.gnu.org/licenses/lgpl.html) * */ public class GCCoreTileEntitySolar extends GCCoreTileEntityUniversalElectrical implements IMultiBlock, IPacketReceiver, IDisableableMachine, IInventory, ISidedInventory { public HashSet<TileEntity> connectedTiles = new HashSet<TileEntity>(); public Vector3 mainBlockPosition; public int solarStrength = 0; public float targetAngle; public float currentAngle; public boolean disabled = true; public int disableCooldown = 0; private ItemStack[] containingItems = new ItemStack[1]; public static final float MAX_GENERATE_WATTS = 15.0F; public float generateWatts = 0; private float ueMaxEnergy; public GCCoreTileEntitySolar() { this(0); } public GCCoreTileEntitySolar(float maxEnergy) { this.ueMaxEnergy = maxEnergy; } public void setMainBlock(Vector3 mainBlock) { this.mainBlockPosition = mainBlock; if (!this.worldObj.isRemote) { this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); } } @Override public void updateEntity() { this.setEnergyStored(this.getEnergyStored() + this.generateWatts); super.updateEntity(); if (!this.worldObj.isRemote) { this.recharge(this.containingItems[0]); if (this.disableCooldown > 0) { this.disableCooldown--; } if (!this.getDisabled(0) && this.ticks % 20 == 0) { this.solarStrength = 0; if (this.worldObj.isDaytime() && (this.worldObj.provider instanceof IGalacticraftWorldProvider || !this.worldObj.isRaining() && !this.worldObj.isThundering())) { double distance = 100.0D; double sinA = -Math.sin((this.currentAngle - 77.5D) * Math.PI / 180.0D); double cosA = Math.abs(Math.cos((this.currentAngle - 77.5D) * Math.PI / 180.0D)); for (int x = -1; x <= 1; x++) { for (int z = -1; z <= 1; z++) { if (this.getBlockMetadata() < GCCoreBlockSolar.ADVANCED_METADATA) { if (this.worldObj.canBlockSeeTheSky(this.xCoord + x, this.yCoord + 2, this.zCoord + z)) { boolean valid = true; for (int y = this.yCoord + 3; y < 256; y++) { int blockID = this.worldObj.getBlockId(this.xCoord + x, y, this.zCoord + z); if (blockID != 0 && Block.blocksList[blockID].isOpaqueCube()) { valid = false; break; } } if (valid) { this.solarStrength++; } } } else { boolean valid = true; for (double d = 0.0D; d < distance; d++) { Vector3 thisVec = new Vector3(this); Vector3 blockAt = thisVec.clone().translate(new Vector3(x, 3, z)).clone() .translate(new Vector3(d * sinA, d * cosA, 0)); int blockID = blockAt.getBlockID(this.worldObj); if (blockID != 0 && Block.blocksList[blockID].isOpaqueCube()) { valid = false; break; } } if (valid) { this.solarStrength++; } } } } } } } float angle = this.worldObj.getCelestialAngle(1.0F) - 0.7845194F < 0 ? 1.0F - 0.7845194F : -0.7845194F; float celestialAngle = (this.worldObj.getCelestialAngle(1.0F) + angle) * 360.0F; celestialAngle %= 360; if (this.getBlockMetadata() >= GCCoreBlockSolar.ADVANCED_METADATA) { if (celestialAngle > 30 && celestialAngle < 150) { float difference = this.targetAngle - celestialAngle; this.targetAngle -= difference / 20.0F; } else if (!this.worldObj.isDaytime() || this.worldObj.isRaining() || this.worldObj.isThundering()) { this.targetAngle = 77.5F + 180.0F; } else if (celestialAngle < 50) { this.targetAngle = 50; } else if (celestialAngle > 150) { this.targetAngle = 150; } } else { if (!this.worldObj.isDaytime() || this.worldObj.isRaining() || this.worldObj.isThundering()) { this.targetAngle = 77.5F + 180.0F; } else { this.targetAngle = 77.5F; } } float difference = this.targetAngle - this.currentAngle; this.currentAngle += difference / 20.0F; if (!this.worldObj.isRemote) { if (this.getGenerate() > 0.0F) { this.generateWatts = Math.min(Math.max(this.getGenerate(), 0), GCCoreTileEntitySolar.MAX_GENERATE_WATTS) / 20.0F; } else { this.generateWatts = 0.0F; } } this.produce(); if (this.ticks % 3 == 0) { GCCorePacketManager.sendPacketToClients(this.getDescriptionPacket(), this.worldObj, new Vector3(this), 50); } } public float getGenerate() { if (this.getDisabled(0)) { return 0.0F; } float angle = this.worldObj.getCelestialAngle(1.0F) - 0.784690560F < 0 ? 1.0F - 0.784690560F : -0.784690560F; float celestialAngle = (this.worldObj.getCelestialAngle(1.0F) + angle) * 360.0F; celestialAngle %= 360; float difference = (180.0F - Math.abs(this.currentAngle % 180 - celestialAngle)) / 180.0F; return 1 / 1000.0F * difference * difference * (this.solarStrength * (Math.abs(difference) * 500.0F)) * this.getSolarBoost(); } public float getSolarBoost() { return (float) (this.worldObj.provider instanceof ISolarLevel ? ((ISolarLevel) this.worldObj.provider).getSolarEnergyMultiplier() : 1.0F); } @Override public void handlePacketData(INetworkManager network, int packetType, Packet250CustomPayload packet, EntityPlayer player, ByteArrayDataInput dataStream) { try { this.mainBlockPosition = new Vector3(dataStream.readInt(), dataStream.readInt(), dataStream.readInt()); this.solarStrength = dataStream.readInt(); this.setEnergyStored(dataStream.readFloat()); this.generateWatts = dataStream.readFloat(); this.disableCooldown = dataStream.readInt(); this.disabled = dataStream.readBoolean(); } catch (Exception e) { e.printStackTrace(); } } @Override public Packet getDescriptionPacket() { return GCCorePacketManager.getPacket(GalacticraftCore.CHANNELENTITIES, this, this.mainBlockPosition != null ? this.mainBlockPosition.intX() : 0, this.mainBlockPosition != null ? this.mainBlockPosition.intY() : 0, this.mainBlockPosition != null ? this.mainBlockPosition.intZ() : 0, this.solarStrength, this.getEnergyStored(), this.generateWatts, this.disableCooldown, this.disabled); } public void onBlockRemoval() { if (this.mainBlockPosition != null) { TileEntity tileEntity = this.worldObj.getBlockTileEntity(this.mainBlockPosition.intX(), this.mainBlockPosition.intY(), this.mainBlockPosition.intZ()); if (tileEntity != null && tileEntity instanceof IMultiBlock) { IMultiBlock mainBlock = (IMultiBlock) tileEntity; if (mainBlock != null) { mainBlock.onDestroy(this); } } } } @Override public boolean onActivated(EntityPlayer entityPlayer) { return this.getBlockType().onBlockActivated(this.worldObj, this.xCoord, this.yCoord, this.zCoord, entityPlayer, 0, this.xCoord, this.yCoord, this.zCoord); } @Override public boolean canUpdate() { return true; } @Override public void onCreate(Vector3 placedPosition) { this.mainBlockPosition = placedPosition; for (int y = 1; y <= 2; y++) { for (int x = -1; x < 2; x++) { for (int z = -1; z < 2; z++) { final Vector3 vecToAdd = new Vector3(placedPosition.x + (y == 2 ? x : 0), placedPosition.y + y, placedPosition.z + (y == 2 ? z : 0)); if (!vecToAdd.equals(placedPosition)) { ((GCCoreBlockMulti) GCCoreBlocks.fakeBlock).makeFakeBlock(this.worldObj, vecToAdd, placedPosition, 4); } } } } } @Override public void onDestroy(TileEntity callingBlock) { final Vector3 thisBlock = new Vector3(this); for (int y = 1; y <= 2; y++) { for (int x = -1; x < 2; x++) { for (int z = -1; z < 2; z++) { if (this.worldObj.isRemote && this.worldObj.rand.nextDouble() < 0.1D) { FMLClientHandler.instance().getClient().effectRenderer.addBlockDestroyEffects( thisBlock.intX() + (y == 2 ? x : 0), thisBlock.intY() + y, thisBlock.intZ() + (y == 2 ? z : 0), GCCoreBlocks.solarPanel.blockID & 4095, GCCoreBlocks.solarPanel.blockID >> 12 & 255); } this.worldObj.destroyBlock(thisBlock.intX() + (y == 2 ? x : 0), thisBlock.intY() + y, thisBlock.intZ() + (y == 2 ? z : 0), false); } } } this.worldObj.destroyBlock(thisBlock.intX(), thisBlock.intY(), thisBlock.intZ(), true); this.worldObj.setBlock(thisBlock.intX(), thisBlock.intY(), thisBlock.intZ(), 0, 0, 3); } @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); this.mainBlockPosition = new Vector3(nbt.getCompoundTag("mainBlockPosition")); this.ueMaxEnergy = nbt.getFloat("maxEnergy"); if (this.ueMaxEnergy > 1000.0F) { this.ueMaxEnergy /= 1000.0F; } this.currentAngle = nbt.getFloat("currentAngle"); this.targetAngle = nbt.getFloat("targetAngle"); this.setDisabled(0, nbt.getBoolean("disabled")); this.disableCooldown = nbt.getInteger("disabledCooldown"); final NBTTagList var2 = nbt.getTagList("Items"); this.containingItems = new ItemStack[this.getSizeInventory()]; for (int var3 = 0; var3 < var2.tagCount(); ++var3) { final NBTTagCompound var4 = (NBTTagCompound) var2.tagAt(var3); final byte var5 = var4.getByte("Slot"); if (var5 >= 0 && var5 < this.containingItems.length) { this.containingItems[var5] = ItemStack.loadItemStackFromNBT(var4); } } } @Override public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); if (this.mainBlockPosition != null) { nbt.setCompoundTag("mainBlockPosition", this.mainBlockPosition.writeToNBT(new NBTTagCompound())); } nbt.setFloat("maxEnergy", this.getMaxEnergyStored()); nbt.setFloat("currentAngle", this.currentAngle); nbt.setFloat("targetAngle", this.targetAngle); nbt.setInteger("disabledCooldown", this.disableCooldown); nbt.setBoolean("disabled", this.getDisabled(0)); final NBTTagList list = new NBTTagList(); for (int var3 = 0; var3 < this.containingItems.length; ++var3) { if (this.containingItems[var3] != null) { final NBTTagCompound var4 = new NBTTagCompound(); var4.setByte("Slot", (byte) var3); this.containingItems[var3].writeToNBT(var4); list.appendTag(var4); } } nbt.setTag("Items", list); } @Override public float getRequest(ForgeDirection direction) { return 0; } @Override public float getProvide(ForgeDirection direction) { return this.getElectricalOutputDirections().contains(direction) ? Math.min(Math.max(this.getEnergyStored(), 0), 1300) : 0; } @Override public EnumSet<ForgeDirection> getElectricalInputDirections() { return EnumSet.noneOf(ForgeDirection.class); } @Override public EnumSet<ForgeDirection> getElectricalOutputDirections() { int metadata = this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord); if (metadata >= GCCoreBlockSolar.ADVANCED_METADATA) { metadata -= GCCoreBlockSolar.ADVANCED_METADATA; } return EnumSet.of(ForgeDirection.getOrientation(metadata + 2).getOpposite(), ForgeDirection.UNKNOWN); } @Override @SideOnly(Side.CLIENT) public AxisAlignedBB getRenderBoundingBox() { return TileEntity.INFINITE_EXTENT_AABB; } @Override public boolean isInvNameLocalized() { return true; } @Override public String getInvName() { return StatCollector.translateToLocal( this.getBlockMetadata() < GCCoreBlockSolar.ADVANCED_METADATA ? "container.solarbasic.name" : "container.solaradvanced.name"); } @Override public void setDisabled(int index, boolean disabled) { if (this.disableCooldown == 0) { this.disabled = disabled; this.disableCooldown = 20; } } @Override public boolean getDisabled(int index) { return this.disabled; } public int getScaledElecticalLevel(int i) { return (int) Math.floor(this.getEnergyStored() * i / this.getMaxEnergyStored()); } @Override public int getSizeInventory() { return this.containingItems.length; } @Override public ItemStack getStackInSlot(int par1) { return this.containingItems[par1]; } @Override public ItemStack decrStackSize(int par1, int par2) { if (this.containingItems[par1] != null) { ItemStack var3; if (this.containingItems[par1].stackSize <= par2) { var3 = this.containingItems[par1]; this.containingItems[par1] = null; return var3; } else { var3 = this.containingItems[par1].splitStack(par2); if (this.containingItems[par1].stackSize == 0) { this.containingItems[par1] = null; } return var3; } } else { return null; } } @Override public ItemStack getStackInSlotOnClosing(int par1) { if (this.containingItems[par1] != null) { final ItemStack var2 = this.containingItems[par1]; this.containingItems[par1] = null; return var2; } else { return null; } } @Override public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { this.containingItems[par1] = par2ItemStack; if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit()) { par2ItemStack.stackSize = this.getInventoryStackLimit(); } } @Override public int getInventoryStackLimit() { return 64; } @Override public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false : par1EntityPlayer.getDistanceSq(this.xCoord + 0.5D, this.yCoord + 0.5D, this.zCoord + 0.5D) <= 64.0D; } @Override public void openChest() { } @Override public void closeChest() { } @Override public int[] getAccessibleSlotsFromSide(int side) { return new int[] { 0 }; } @Override public boolean canInsertItem(int slotID, ItemStack itemstack, int side) { return this.isItemValidForSlot(slotID, itemstack); } @Override public boolean canExtractItem(int slotID, ItemStack itemstack, int side) { return slotID == 0; } @Override public boolean isItemValidForSlot(int slotID, ItemStack itemstack) { return slotID == 0 ? itemstack.getItem() instanceof IItemElectric : false; } @Override public float getMaxEnergyStored() { return this.ueMaxEnergy; } }