Java tutorial
/* * Copyright (C) 2012,2013 yogpstop This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this program. * If not, see <http://www.gnu.org/licenses/>. */ package com.yogpc.qp.tile; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.UUID; import net.minecraft.block.Block; import net.minecraft.enchantment.Enchantment; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.common.util.ForgeDirection; import cofh.api.inventory.IInventoryConnection; import com.gamerforea.quarryplus.FakePlayerUtils; import com.google.common.base.Strings; import com.google.common.io.ByteArrayDataInput; import com.google.common.io.ByteStreams; import com.yogpc.qp.InvUtils; import com.yogpc.qp.PacketHandler; import com.yogpc.qp.PowerManager; import com.yogpc.qp.QuarryPlusI.BlockData; import com.yogpc.qp.ReflectionHelper; import cpw.mods.fml.common.Optional; import cpw.mods.fml.common.registry.GameData; @Optional.Interface(iface = "cofh.api.inventory.IInventoryConnection", modid = "CoFHAPI|inventory") public abstract class TileBasic extends APowerTile implements IEnchantableTile, IInventory, IInventoryConnection { protected ForgeDirection pump = ForgeDirection.UNKNOWN; public final List<BlockData> fortuneList = new ArrayList<BlockData>(); public final List<BlockData> silktouchList = new ArrayList<BlockData>(); public boolean fortuneInclude, silktouchInclude; protected byte unbreaking; protected byte fortune; protected boolean silktouch; protected byte efficiency; protected final LinkedList<ItemStack> cacheItems = new LinkedList<ItemStack>(); // TODO gamerforEA code start public UUID ownerUUID; public String ownerName; private FakePlayer fakePlayer; public FakePlayer getFakePlayer() { FakePlayer player = null; if (!Strings.isNullOrEmpty(this.ownerName) && this.ownerUUID != null) { if (this.fakePlayer == null) this.fakePlayer = FakePlayerUtils.createFakePlayer(this.ownerUUID, this.ownerName, this.worldObj); player = this.fakePlayer; } else player = FakePlayerUtils.getPlayer(this.worldObj); return player; } // TODO gamerforEA code end @Override public void S_recievePacket(final byte id, final byte[] data, final EntityPlayer ep) { final ByteArrayDataInput badi = ByteStreams.newDataInput(data); switch (id) { case PacketHandler.CtS_REMOVE_FORTUNE: this.fortuneList.remove(new BlockData(badi.readUTF(), badi.readInt())); break; case PacketHandler.CtS_REMOVE_SILKTOUCH: this.silktouchList.remove(new BlockData(badi.readUTF(), badi.readInt())); break; case PacketHandler.CtS_TOGGLE_FORTUNE: this.fortuneInclude = !this.fortuneInclude; break; case PacketHandler.CtS_TOGGLE_SILKTOUCH: this.silktouchInclude = !this.silktouchInclude; break; } } public abstract void G_renew_powerConfigure(); protected abstract void G_destroy(); @Override public final void onChunkUnload() { G_destroy(); super.onChunkUnload(); } @Override public void C_recievePacket(final byte id, final byte[] data, final EntityPlayer ep) { } protected void S_pollItems() { ItemStack is; while (null != (is = this.cacheItems.poll())) { InvUtils.injectToNearTile(this.worldObj, this.xCoord, this.yCoord, this.zCoord, is); if (is.stackSize > 0) { this.cacheItems.add(is); break; } } } protected boolean S_breakBlock(final int x, final int y, final int z) { // TODO gamerforEA code start if (FakePlayerUtils.callBlockBreakEvent(x, y, z, this.getFakePlayer()).isCancelled()) return false; // TODO gamerforEA code end final Collection<ItemStack> dropped = new LinkedList<ItemStack>(); final Block b = this.worldObj.getChunkProvider().loadChunk(x >> 4, z >> 4).getBlock(x & 0xF, y, z & 0xF); if (b == null || b.isAir(this.worldObj, x, y, z)) return true; if (TilePump.isLiquid(b, false, null, 0, 0, 0, 0)) { final TileEntity te = this.worldObj.getTileEntity(this.xCoord + this.pump.offsetX, this.yCoord + this.pump.offsetY, this.zCoord + this.pump.offsetZ); if (!(te instanceof TilePump)) { this.pump = ForgeDirection.UNKNOWN; G_renew_powerConfigure(); return true; } return ((TilePump) te).S_removeLiquids(this, x, y, z); } if (!PowerManager.useEnergyB(this, b.getBlockHardness(this.worldObj, x, y, z), S_addDroppedItems(dropped, b, x, y, z), this.unbreaking)) return false; this.cacheItems.addAll(dropped); this.worldObj.playAuxSFXAtEntity(null, 2001, x, y, z, Block.getIdFromBlock(b) | this.worldObj.getBlockMetadata(x, y, z) << 12); this.worldObj.setBlockToAir(x, y, z); return true; } boolean S_connect(final ForgeDirection fd) { final TileEntity te = this.worldObj.getTileEntity(this.xCoord + this.pump.offsetX, this.yCoord + this.pump.offsetY, this.zCoord + this.pump.offsetZ); if (te instanceof TilePump && this.pump != fd) return false; this.pump = fd; G_renew_powerConfigure(); return true; } private byte S_addDroppedItems(final Collection<ItemStack> list, final Block b, final int x, final int y, final int z) { final int meta = this.worldObj.getBlockMetadata(x, y, z); if (b.canSilkHarvest(this.worldObj, null, x, y, z, meta) && this.silktouch && this.silktouchList.contains( new BlockData(GameData.getBlockRegistry().getNameForObject(b), meta)) == this.silktouchInclude) { list.add((ItemStack) ReflectionHelper.invoke(createStackedBlock, b, new Integer(meta))); return -1; } if (this.fortuneList.contains( new BlockData(GameData.getBlockRegistry().getNameForObject(b), meta)) == this.fortuneInclude) { list.addAll(b.getDrops(this.worldObj, x, y, z, meta, this.fortune)); return this.fortune; } list.addAll(b.getDrops(this.worldObj, x, y, z, meta, 0)); return 0; } public static final Method createStackedBlock = ReflectionHelper.getMethod(Block.class, new String[] { "func_149644_j", "createStackedBlock" }, new Class<?>[] { int.class }); @Override public void readFromNBT(final NBTTagCompound nbttc) { super.readFromNBT(nbttc); this.silktouch = nbttc.getBoolean("silktouch"); this.fortune = nbttc.getByte("fortune"); this.efficiency = nbttc.getByte("efficiency"); this.unbreaking = nbttc.getByte("unbreaking"); this.fortuneInclude = nbttc.getBoolean("fortuneInclude"); this.silktouchInclude = nbttc.getBoolean("silktouchInclude"); readLongCollection(nbttc.getTagList("fortuneList", 10), this.fortuneList); readLongCollection(nbttc.getTagList("silktouchList", 10), this.silktouchList); // TODO gamerforEA code start String uuid = nbttc.getString("ownerUUID"); if (!Strings.isNullOrEmpty(uuid)) this.ownerUUID = UUID.fromString(uuid); String name = nbttc.getString("ownerName"); if (!Strings.isNullOrEmpty(name)) this.ownerName = name; // TODO gamerforEA code end } private static void readLongCollection(final NBTTagList nbttl, final Collection<BlockData> target) { target.clear(); for (int i = 0; i < nbttl.tagCount(); i++) { final NBTTagCompound c = nbttl.getCompoundTagAt(i); target.add(new BlockData(c.getString("name"), c.getInteger("meta"))); } } @Override public void writeToNBT(final NBTTagCompound nbttc) { super.writeToNBT(nbttc); nbttc.setBoolean("silktouch", this.silktouch); nbttc.setByte("fortune", this.fortune); nbttc.setByte("efficiency", this.efficiency); nbttc.setByte("unbreaking", this.unbreaking); nbttc.setBoolean("fortuneInclude", this.fortuneInclude); nbttc.setBoolean("silktouchInclude", this.silktouchInclude); nbttc.setTag("fortuneList", writeLongCollection(this.fortuneList)); nbttc.setTag("silktouchList", writeLongCollection(this.silktouchList)); // TODO gamerforEA code start if (this.ownerUUID != null) nbttc.setString("ownerUUID", this.ownerUUID.toString()); if (!Strings.isNullOrEmpty(this.ownerName)) nbttc.setString("ownerName", this.ownerName); // TODO gamerforEA code end } private static NBTTagList writeLongCollection(final Collection<BlockData> target) { final NBTTagList nbttl = new NBTTagList(); for (final BlockData l : target) { final NBTTagCompound c = new NBTTagCompound(); c.setString("name", l.name); c.setInteger("meta", l.meta); nbttl.appendTag(c); } return nbttl; } @Override public Map<Integer, Byte> get() { final Map<Integer, Byte> ret = new HashMap<Integer, Byte>(); if (this.efficiency > 0) ret.put(Integer.valueOf(Enchantment.efficiency.effectId), Byte.valueOf(this.efficiency)); if (this.fortune > 0) ret.put(Integer.valueOf(Enchantment.fortune.effectId), Byte.valueOf(this.fortune)); if (this.unbreaking > 0) ret.put(Integer.valueOf(Enchantment.unbreaking.effectId), Byte.valueOf(this.unbreaking)); if (this.silktouch) ret.put(Integer.valueOf(Enchantment.silkTouch.effectId), Byte.valueOf((byte) 1)); return ret; } @Override public void set(final int id, final byte val) { if (id == Enchantment.efficiency.effectId) this.efficiency = val; else if (id == Enchantment.fortune.effectId) this.fortune = val; else if (id == Enchantment.unbreaking.effectId) this.unbreaking = val; else if (id == Enchantment.silkTouch.effectId && val > 0) this.silktouch = true; } @Override public int getSizeInventory() { return Math.max(1, this.cacheItems.size()); } @Override public ItemStack getStackInSlot(final int i) {// NOTE better way? return i < 0 || i >= this.cacheItems.size() ? new ItemStack(Blocks.cobblestone, 0) : this.cacheItems.get(i); } @Override public ItemStack decrStackSize(final int i, final int a) { if (i < 0 || i >= this.cacheItems.size()) return null; final ItemStack from = this.cacheItems.get(i); final ItemStack res = new ItemStack(from.getItem(), Math.min(a, from.stackSize), from.getItemDamage()); if (from.stackTagCompound != null) res.stackTagCompound = (NBTTagCompound) from.stackTagCompound.copy(); from.stackSize -= res.stackSize; if (from.stackSize == 0) this.cacheItems.remove(i); return res; } @Override public ItemStack getStackInSlotOnClosing(final int i) { return i < 0 || i >= this.cacheItems.size() ? new ItemStack(Blocks.cobblestone, 0) : this.cacheItems.get(i); } @Override public void setInventorySlotContents(final int i, final ItemStack is) { if (is != null && is.stackSize > 0) System.err.println("QuarryPlus WARN: call setInventorySlotContents with non null ItemStack."); if (i >= 0 && i < this.cacheItems.size()) this.cacheItems.remove(i); } @Override public String getInventoryName() { return "container.yog.basic"; } @Override public boolean hasCustomInventoryName() { return false; } @Override public int getInventoryStackLimit() { return 0; } @Override public void markDirty() { } @Override public boolean isUseableByPlayer(final EntityPlayer p_70300_1_) { return false; } @Override public void openInventory() { } @Override public void closeInventory() { } @Override public boolean isItemValidForSlot(final int p_94041_1_, final ItemStack p_94041_2_) { return false; } @Override @Optional.Method(modid = "CoFHAPI|inventory") public ConnectionType canConnectInventory(final ForgeDirection arg0) { return ConnectionType.FORCE; } }