package net.minecraft.server; import java.util.Arrays; import java.util.Iterator; import javax.annotation.Nullable; // CraftBukkit start import java.util.List; import org.bukkit.craftbukkit.entity.CraftHumanEntity; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.entity.HumanEntity; import org.bukkit.event.inventory.BrewEvent; import org.bukkit.event.inventory.BrewingStandFuelEvent; import org.bukkit.inventory.InventoryHolder; // CraftBukkit end public class TileEntityBrewingStand extends TileEntityContainer implements IWorldInventory, ITickable { private static final int[] b = new int[]{3}; private static final int[] c = new int[]{0, 1, 2, 3}; private static final int[] g = new int[]{0, 1, 2, 4}; private NonNullList<ItemStack> items; public int brewTime; private boolean[] j; private Item k; public int fuelLevel; protected final IContainerProperties a; // CraftBukkit start - add fields and methods private int lastTick = MinecraftServer.currentTick; public List<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>(); private int maxStack = 64; public void onOpen(CraftHumanEntity who) { transaction.add(who); } public void onClose(CraftHumanEntity who) { transaction.remove(who); } public List<HumanEntity> getViewers() { return transaction; } public List<ItemStack> getContents() { return this.items; } @Override public int getMaxStackSize() { return maxStack; } public void setMaxStackSize(int size) { maxStack = size; } // CraftBukkit end public TileEntityBrewingStand() { super(TileEntityTypes.BREWING_STAND); this.items = NonNullList.a(5, ItemStack.a); this.a = new IContainerProperties() { @Override public int getProperty(int i) { switch (i) { case 0: return TileEntityBrewingStand.this.brewTime; case 1: return TileEntityBrewingStand.this.fuelLevel; default: return 0; } } @Override public void setProperty(int i, int j) { switch (i) { case 0: TileEntityBrewingStand.this.brewTime = j; break; case 1: TileEntityBrewingStand.this.fuelLevel = j; } } @Override public int a() { return 2; } }; } @Override protected IChatBaseComponent getContainerName() { return new ChatMessage("container.brewing", new Object[0]); } @Override public int getSize() { return this.items.size(); } @Override public boolean isEmpty() { Iterator iterator = this.items.iterator(); ItemStack itemstack; do { if (!iterator.hasNext()) { return true; } itemstack = (ItemStack) iterator.next(); } while (itemstack.isEmpty()); return false; } @Override public void tick() { ItemStack itemstack = (ItemStack) this.items.get(4); if (this.fuelLevel <= 0 && itemstack.getItem() == Items.BLAZE_POWDER) { // CraftBukkit start BrewingStandFuelEvent event = new BrewingStandFuelEvent(world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()), CraftItemStack.asCraftMirror(itemstack), 20); this.world.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { return; } this.fuelLevel = event.getFuelPower(); if (this.fuelLevel > 0 && event.isConsuming()) { itemstack.subtract(1); } // CraftBukkit end this.update(); } boolean flag = this.h(); boolean flag1 = this.brewTime > 0; ItemStack itemstack1 = (ItemStack) this.items.get(3); // CraftBukkit start - Use wall time instead of ticks for brewing int elapsedTicks = MinecraftServer.currentTick - this.lastTick; this.lastTick = MinecraftServer.currentTick; if (flag1) { this.brewTime -= elapsedTicks; boolean flag2 = this.brewTime <= 0; // == -> <= // CraftBukkit end if (flag2 && flag) { this.j(); this.update(); } else if (!flag) { this.brewTime = 0; this.update(); } else if (this.k != itemstack1.getItem()) { this.brewTime = 0; this.update(); } } else if (flag && this.fuelLevel > 0) { --this.fuelLevel; this.brewTime = 400; this.k = itemstack1.getItem(); this.update(); } if (!this.world.isClientSide) { boolean[] aboolean = this.f(); if (!Arrays.equals(aboolean, this.j)) { this.j = aboolean; IBlockData iblockdata = this.world.getType(this.getPosition()); if (!(iblockdata.getBlock() instanceof BlockBrewingStand)) { return; } for (int i = 0; i < BlockBrewingStand.HAS_BOTTLE.length; ++i) { iblockdata = (IBlockData) iblockdata.set(BlockBrewingStand.HAS_BOTTLE[i], aboolean[i]); } this.world.setTypeAndData(this.position, iblockdata, 2); } } } public boolean[] f() { boolean[] aboolean = new boolean[3]; for (int i = 0; i < 3; ++i) { if (!((ItemStack) this.items.get(i)).isEmpty()) { aboolean[i] = true; } } return aboolean; } private boolean h() { ItemStack itemstack = (ItemStack) this.items.get(3); if (itemstack.isEmpty()) { return false; } else if (!PotionBrewer.a(itemstack)) { return false; } else { for (int i = 0; i < 3; ++i) { ItemStack itemstack1 = (ItemStack) this.items.get(i); if (!itemstack1.isEmpty() && PotionBrewer.a(itemstack1, itemstack)) { return true; } } return false; } } private void j() { ItemStack itemstack = (ItemStack) this.items.get(3); // CraftBukkit start InventoryHolder owner = this.getOwner(); if (owner != null) { BrewEvent event = new BrewEvent(world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()), (org.bukkit.inventory.BrewerInventory) owner.getInventory(), this.fuelLevel); org.bukkit.Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { return; } } // CraftBukkit end for (int i = 0; i < 3; ++i) { this.items.set(i, PotionBrewer.d(itemstack, (ItemStack) this.items.get(i))); } itemstack.subtract(1); BlockPosition blockposition = this.getPosition(); if (itemstack.getItem().q()) { ItemStack itemstack1 = new ItemStack(itemstack.getItem().p()); if (itemstack.isEmpty()) { itemstack = itemstack1; } else if (!this.world.isClientSide) { InventoryUtils.dropItem(this.world, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), itemstack1); } } this.items.set(3, itemstack); this.world.triggerEffect(1035, blockposition, 0); } @Override public void load(NBTTagCompound nbttagcompound) { super.load(nbttagcompound); this.items = NonNullList.a(this.getSize(), ItemStack.a); ContainerUtil.b(nbttagcompound, this.items); this.brewTime = nbttagcompound.getShort("BrewTime"); this.fuelLevel = nbttagcompound.getByte("Fuel"); } @Override public NBTTagCompound save(NBTTagCompound nbttagcompound) { super.save(nbttagcompound); nbttagcompound.setShort("BrewTime", (short) this.brewTime); ContainerUtil.a(nbttagcompound, this.items); nbttagcompound.setByte("Fuel", (byte) this.fuelLevel); return nbttagcompound; } @Override public ItemStack getItem(int i) { return i >= 0 && i < this.items.size() ? (ItemStack) this.items.get(i) : ItemStack.a; } @Override public ItemStack splitStack(int i, int j) { return ContainerUtil.a(this.items, i, j); } @Override public ItemStack splitWithoutUpdate(int i) { return ContainerUtil.a(this.items, i); } @Override public void setItem(int i, ItemStack itemstack) { if (i >= 0 && i < this.items.size()) { this.items.set(i, itemstack); } } @Override public boolean a(EntityHuman entityhuman) { return this.world.getTileEntity(this.position) != this ? false : entityhuman.g((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; } @Override public boolean b(int i, ItemStack itemstack) { if (i == 3) { return PotionBrewer.a(itemstack); } else { Item item = itemstack.getItem(); return i == 4 ? item == Items.BLAZE_POWDER : (item == Items.POTION || item == Items.SPLASH_POTION || item == Items.LINGERING_POTION || item == Items.GLASS_BOTTLE) && this.getItem(i).isEmpty(); } } @Override public int[] getSlotsForFace(EnumDirection enumdirection) { return enumdirection == EnumDirection.UP ? TileEntityBrewingStand.b : (enumdirection == EnumDirection.DOWN ? TileEntityBrewingStand.c : TileEntityBrewingStand.g); } @Override public boolean canPlaceItemThroughFace(int i, ItemStack itemstack, @Nullable EnumDirection enumdirection) { return this.b(i, itemstack); } @Override public boolean canTakeItemThroughFace(int i, ItemStack itemstack, EnumDirection enumdirection) { return i == 3 ? itemstack.getItem() == Items.GLASS_BOTTLE : true; } @Override public void clear() { this.items.clear(); } @Override protected Container createContainer(int i, PlayerInventory playerinventory) { return new ContainerBrewingStand(i, playerinventory, this, this.a); } }