diff --git a/sources/src/main/java/net/minecraft/server/DispenserRegistry.java b/sources/src/main/java/net/minecraft/server/DispenserRegistry.java new file mode 100644 index 000000000..be8135f80 --- /dev/null +++ b/sources/src/main/java/net/minecraft/server/DispenserRegistry.java @@ -0,0 +1,868 @@ +package net.minecraft.server; + +import com.mojang.authlib.GameProfile; +import java.io.File; +import java.io.PrintStream; +import java.util.Random; +import java.util.UUID; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +// CraftBukkit start +import java.util.List; +import org.bukkit.Location; +import org.bukkit.TreeType; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.block.BlockDispenseEvent; +import org.bukkit.event.world.StructureGrowEvent; +// CraftBukkit end + +public class DispenserRegistry { + + public static final PrintStream a = System.out; + private static boolean c; + public static boolean b; + private static final Logger d = LogManager.getLogger(); + + public static boolean a() { + return DispenserRegistry.c; + } + + static void b() { + BlockDispenser.REGISTRY.a(Items.ARROW, new DispenseBehaviorProjectile() { + protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { + EntityTippedArrow entitytippedarrow = new EntityTippedArrow(world, iposition.getX(), iposition.getY(), iposition.getZ()); + + entitytippedarrow.fromPlayer = EntityArrow.PickupStatus.ALLOWED; + return entitytippedarrow; + } + }); + BlockDispenser.REGISTRY.a(Items.TIPPED_ARROW, new DispenseBehaviorProjectile() { + protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { + EntityTippedArrow entitytippedarrow = new EntityTippedArrow(world, iposition.getX(), iposition.getY(), iposition.getZ()); + + entitytippedarrow.a(itemstack); + entitytippedarrow.fromPlayer = EntityArrow.PickupStatus.ALLOWED; + return entitytippedarrow; + } + }); + BlockDispenser.REGISTRY.a(Items.SPECTRAL_ARROW, new DispenseBehaviorProjectile() { + protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { + EntitySpectralArrow entityspectralarrow = new EntitySpectralArrow(world, iposition.getX(), iposition.getY(), iposition.getZ()); + + entityspectralarrow.fromPlayer = EntityArrow.PickupStatus.ALLOWED; + return entityspectralarrow; + } + }); + BlockDispenser.REGISTRY.a(Items.EGG, new DispenseBehaviorProjectile() { + protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { + return new EntityEgg(world, iposition.getX(), iposition.getY(), iposition.getZ()); + } + }); + BlockDispenser.REGISTRY.a(Items.SNOWBALL, new DispenseBehaviorProjectile() { + protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { + return new EntitySnowball(world, iposition.getX(), iposition.getY(), iposition.getZ()); + } + }); + BlockDispenser.REGISTRY.a(Items.EXPERIENCE_BOTTLE, new DispenseBehaviorProjectile() { + protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { + return new EntityThrownExpBottle(world, iposition.getX(), iposition.getY(), iposition.getZ()); + } + + protected float a() { + return super.a() * 0.5F; + } + + protected float getPower() { + return super.getPower() * 1.25F; + } + }); + BlockDispenser.REGISTRY.a(Items.SPLASH_POTION, new IDispenseBehavior() { + public ItemStack a(ISourceBlock isourceblock, final ItemStack itemstack) { + return (new DispenseBehaviorProjectile() { + protected IProjectile a(World world, IPosition iposition, ItemStack itemstack1) { // CraftBukkit - decompile issue + return new EntityPotion(world, iposition.getX(), iposition.getY(), iposition.getZ(), itemstack1.cloneItemStack()); + } + + protected float a() { + return super.a() * 0.5F; + } + + protected float getPower() { + return super.getPower() * 1.25F; + } + }).a(isourceblock, itemstack); + } + }); + BlockDispenser.REGISTRY.a(Items.LINGERING_POTION, new IDispenseBehavior() { + public ItemStack a(ISourceBlock isourceblock, final ItemStack itemstack) { + return (new DispenseBehaviorProjectile() { + protected IProjectile a(World world, IPosition iposition, ItemStack itemstack1) { // CraftBukkit - decompile issue + return new EntityPotion(world, iposition.getX(), iposition.getY(), iposition.getZ(), itemstack1.cloneItemStack()); + } + + protected float a() { + return super.a() * 0.5F; + } + + protected float getPower() { + return super.getPower() * 1.25F; + } + }).a(isourceblock, itemstack); + } + }); + BlockDispenser.REGISTRY.a(Items.SPAWN_EGG, new DispenseBehaviorItem() { + public ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + EnumDirection enumdirection = (EnumDirection) isourceblock.e().get(BlockDispenser.FACING); + double d0 = isourceblock.getX() + (double) enumdirection.getAdjacentX(); + double d1 = (double) ((float) (isourceblock.getBlockPosition().getY() + enumdirection.getAdjacentY()) + 0.2F); + double d2 = isourceblock.getZ() + (double) enumdirection.getAdjacentZ(); + // Entity entity = ItemMonsterEgg.a(isourceblock.getWorld(), ItemMonsterEgg.h(itemstack), d0, d1, d2); + + // CraftBukkit start + World world = isourceblock.getWorld(); + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1, d2)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.add(1); + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.add(1); + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + + itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); + + Entity entity = ItemMonsterEgg.spawnCreature(isourceblock.getWorld(), ItemMonsterEgg.h(itemstack), event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DISPENSE_EGG); + + if (entity instanceof EntityLiving && itemstack.hasName()) { + entity.setCustomName(itemstack.getName()); + } + + ItemMonsterEgg.a(isourceblock.getWorld(), (EntityHuman) null, itemstack, entity); + // itemstack.subtract(1);// Handled during event processing + // CraftBukkit end + return itemstack; + } + }); + BlockDispenser.REGISTRY.a(Items.FIREWORKS, new DispenseBehaviorItem() { + public ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + EnumDirection enumdirection = (EnumDirection) isourceblock.e().get(BlockDispenser.FACING); + double d0 = isourceblock.getX() + (double) enumdirection.getAdjacentX(); + double d1 = (double) ((float) isourceblock.getBlockPosition().getY() + 0.2F); + double d2 = isourceblock.getZ() + (double) enumdirection.getAdjacentZ(); + // CraftBukkit start + World world = isourceblock.getWorld(); + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1, d2)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.add(1); + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.add(1); + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + + itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); + EntityFireworks entityfireworks = new EntityFireworks(isourceblock.getWorld(), event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), itemstack1); + + isourceblock.getWorld().addEntity(entityfireworks); + // itemstack.subtract(1); // Handled during event processing + // CraftBukkit end + return itemstack; + } + + protected void a(ISourceBlock isourceblock) { + isourceblock.getWorld().triggerEffect(1004, isourceblock.getBlockPosition(), 0); + } + }); + BlockDispenser.REGISTRY.a(Items.FIRE_CHARGE, new DispenseBehaviorItem() { + public ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + EnumDirection enumdirection = (EnumDirection) isourceblock.e().get(BlockDispenser.FACING); + IPosition iposition = BlockDispenser.a(isourceblock); + double d0 = iposition.getX() + (double) ((float) enumdirection.getAdjacentX() * 0.3F); + double d1 = iposition.getY() + (double) ((float) enumdirection.getAdjacentY() * 0.3F); + double d2 = iposition.getZ() + (double) ((float) enumdirection.getAdjacentZ() * 0.3F); + World world = isourceblock.getWorld(); + Random random = world.random; + double d3 = random.nextGaussian() * 0.05D + (double) enumdirection.getAdjacentX(); + double d4 = random.nextGaussian() * 0.05D + (double) enumdirection.getAdjacentY(); + double d5 = random.nextGaussian() * 0.05D + (double) enumdirection.getAdjacentZ(); + + // CraftBukkit start + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d3, d4, d5)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.add(1); + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.add(1); + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + + EntitySmallFireball fireball = new EntitySmallFireball(world, d0, d1, d2, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ()); + fireball.projectileSource = new org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource((TileEntityDispenser) isourceblock.getTileEntity()); + + world.addEntity(fireball); + // itemstack.subtract(1); // Handled during event processing + // CraftBukkit end + return itemstack; + } + + protected void a(ISourceBlock isourceblock) { + isourceblock.getWorld().triggerEffect(1018, isourceblock.getBlockPosition(), 0); + } + }); + BlockDispenser.REGISTRY.a(Items.aH, new DispenserRegistry.a(EntityBoat.EnumBoatType.OAK)); + BlockDispenser.REGISTRY.a(Items.aI, new DispenserRegistry.a(EntityBoat.EnumBoatType.SPRUCE)); + BlockDispenser.REGISTRY.a(Items.aJ, new DispenserRegistry.a(EntityBoat.EnumBoatType.BIRCH)); + BlockDispenser.REGISTRY.a(Items.aK, new DispenserRegistry.a(EntityBoat.EnumBoatType.JUNGLE)); + BlockDispenser.REGISTRY.a(Items.aM, new DispenserRegistry.a(EntityBoat.EnumBoatType.DARK_OAK)); + BlockDispenser.REGISTRY.a(Items.aL, new DispenserRegistry.a(EntityBoat.EnumBoatType.ACACIA)); + DispenseBehaviorItem dispensebehavioritem = new DispenseBehaviorItem() { + private final DispenseBehaviorItem b = new DispenseBehaviorItem(); + + public ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + ItemBucket itembucket = (ItemBucket) itemstack.getItem(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.e().get(BlockDispenser.FACING)); + + // CraftBukkit start + World world = isourceblock.getWorld(); + int x = blockposition.getX(); + int y = blockposition.getY(); + int z = blockposition.getZ(); + if (world.isEmpty(blockposition) || !world.getType(blockposition).getMaterial().isBuildable()) { + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(x, y, z)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + + itembucket = (ItemBucket) CraftItemStack.asNMSCopy(event.getItem()).getItem(); + } + // CraftBukkit end + + if (itembucket.a((EntityHuman) null, isourceblock.getWorld(), blockposition)) { + // CraftBukkit start - Handle stacked buckets + Item item = Items.BUCKET; + itemstack.subtract(1); + if (itemstack.isEmpty()) { + itemstack.setItem(Items.BUCKET); + itemstack.setCount(1); + } else if (((TileEntityDispenser) isourceblock.getTileEntity()).addItem(new ItemStack(item)) < 0) { + this.b.a(isourceblock, new ItemStack(item)); + } + // CraftBukkit end + return itemstack; + } else { + return this.b.a(isourceblock, itemstack); + } + } + }; + + BlockDispenser.REGISTRY.a(Items.LAVA_BUCKET, dispensebehavioritem); + BlockDispenser.REGISTRY.a(Items.WATER_BUCKET, dispensebehavioritem); + BlockDispenser.REGISTRY.a(Items.BUCKET, new DispenseBehaviorItem() { + private final DispenseBehaviorItem b = new DispenseBehaviorItem(); + + public ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + World world = isourceblock.getWorld(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.e().get(BlockDispenser.FACING)); + IBlockData iblockdata = world.getType(blockposition); + Block block = iblockdata.getBlock(); + Material material = iblockdata.getMaterial(); + Item item; + + if (Material.WATER.equals(material) && block instanceof BlockFluids && ((Integer) iblockdata.get(BlockFluids.LEVEL)).intValue() == 0) { + item = Items.WATER_BUCKET; + } else { + if (!Material.LAVA.equals(material) || !(block instanceof BlockFluids) || ((Integer) iblockdata.get(BlockFluids.LEVEL)).intValue() != 0) { + return super.b(isourceblock, itemstack); + } + + item = Items.LAVA_BUCKET; + } + + // CraftBukkit start + org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + // CraftBukkit end + + world.setAir(blockposition); + itemstack.subtract(1); + if (itemstack.isEmpty()) { + return new ItemStack(item); + } else { + if (((TileEntityDispenser) isourceblock.getTileEntity()).addItem(new ItemStack(item)) < 0) { + this.b.a(isourceblock, new ItemStack(item)); + } + + return itemstack; + } + } + }); + BlockDispenser.REGISTRY.a(Items.FLINT_AND_STEEL, new DispenserRegistry.b() { + protected ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + World world = isourceblock.getWorld(); + + // CraftBukkit start + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + // CraftBukkit end + + this.b = true; + BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.e().get(BlockDispenser.FACING)); + + if (world.isEmpty(blockposition)) { + // CraftBukkit start - Ignition by dispensing flint and steel + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()).isCancelled()) { + world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); + if (itemstack.isDamaged(1, world.random, (EntityPlayer) null)) { + itemstack.setCount(0); + } + } + // CraftBukkit end + } else if (world.getType(blockposition).getBlock() == Blocks.TNT) { + Blocks.TNT.postBreak(world, blockposition, Blocks.TNT.getBlockData().set(BlockTNT.EXPLODE, Boolean.valueOf(true))); + world.setAir(blockposition); + } else { + this.b = false; + } + + return itemstack; + } + }); + BlockDispenser.REGISTRY.a(Items.DYE, new DispenserRegistry.b() { + protected ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + this.b = true; + if (EnumColor.WHITE == EnumColor.fromInvColorIndex(itemstack.getData())) { + World world = isourceblock.getWorld(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.e().get(BlockDispenser.FACING)); + + // CraftBukkit start + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + + world.captureTreeGeneration = true; + // CraftBukkit end + + if (ItemDye.a(itemstack, world, blockposition)) { + if (!world.isClientSide) { + world.triggerEffect(2005, blockposition, 0); + } + } else { + this.b = false; + } + // CraftBukkit start + world.captureTreeGeneration = false; + if (world.capturedBlockStates.size() > 0) { + TreeType treeType = BlockSapling.treeType; + BlockSapling.treeType = null; + Location location = new Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); + List blocks = (List) world.capturedBlockStates.clone(); + world.capturedBlockStates.clear(); + StructureGrowEvent structureEvent = null; + if (treeType != null) { + structureEvent = new StructureGrowEvent(location, treeType, false, null, blocks); + org.bukkit.Bukkit.getPluginManager().callEvent(structureEvent); + } + if (structureEvent == null || !structureEvent.isCancelled()) { + for (org.bukkit.block.BlockState blockstate : blocks) { + blockstate.update(true); + } + } + } + // CraftBukkit end + + return itemstack; + } else { + return super.b(isourceblock, itemstack); + } + } + }); + BlockDispenser.REGISTRY.a(Item.getItemOf(Blocks.TNT), new DispenseBehaviorItem() { + protected ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + World world = isourceblock.getWorld(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.e().get(BlockDispenser.FACING)); + // EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, (EntityLiving) null); + + // CraftBukkit start + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector((double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.add(1); + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.add(1); + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + + EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), (EntityLiving) null); + // CraftBukkit end + + world.addEntity(entitytntprimed); + world.a((EntityHuman) null, entitytntprimed.locX, entitytntprimed.locY, entitytntprimed.locZ, SoundEffects.hW, SoundCategory.BLOCKS, 1.0F, 1.0F); + // itemstack.subtract(1); // CraftBukkit - handled above + return itemstack; + } + }); + BlockDispenser.REGISTRY.a(Items.SKULL, new DispenserRegistry.b() { + protected ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + World world = isourceblock.getWorld(); + EnumDirection enumdirection = (EnumDirection) isourceblock.e().get(BlockDispenser.FACING); + BlockPosition blockposition = isourceblock.getBlockPosition().shift(enumdirection); + BlockSkull blockskull = Blocks.SKULL; + + // CraftBukkit start + org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + // CraftBukkit end + + this.b = true; + if (world.isEmpty(blockposition) && blockskull.b(world, blockposition, itemstack)) { + if (!world.isClientSide) { + world.setTypeAndData(blockposition, blockskull.getBlockData().set(BlockSkull.FACING, EnumDirection.UP), 3); + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntitySkull) { + if (itemstack.getData() == 3) { + GameProfile gameprofile = null; + + if (itemstack.hasTag()) { + NBTTagCompound nbttagcompound = itemstack.getTag(); + + if (nbttagcompound.hasKeyOfType("SkullOwner", 10)) { + gameprofile = GameProfileSerializer.deserialize(nbttagcompound.getCompound("SkullOwner")); + } else if (nbttagcompound.hasKeyOfType("SkullOwner", 8)) { + String s = nbttagcompound.getString("SkullOwner"); + + if (!UtilColor.b(s)) { + gameprofile = new GameProfile((UUID) null, s); + } + } + } + + ((TileEntitySkull) tileentity).setGameProfile(gameprofile); + } else { + ((TileEntitySkull) tileentity).setSkullType(itemstack.getData()); + } + + ((TileEntitySkull) tileentity).setRotation(enumdirection.opposite().get2DRotationValue() * 4); + Blocks.SKULL.a(world, blockposition, (TileEntitySkull) tileentity); + } + + itemstack.subtract(1); + } + } else if (ItemArmor.a(isourceblock, itemstack).isEmpty()) { + this.b = false; + } + + return itemstack; + } + }); + BlockDispenser.REGISTRY.a(Item.getItemOf(Blocks.PUMPKIN), new DispenserRegistry.b() { + protected ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + World world = isourceblock.getWorld(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.e().get(BlockDispenser.FACING)); + BlockPumpkin blockpumpkin = (BlockPumpkin) Blocks.PUMPKIN; + + // CraftBukkit start + org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + // CraftBukkit end + + this.b = true; + if (world.isEmpty(blockposition) && blockpumpkin.b(world, blockposition)) { + if (!world.isClientSide) { + world.setTypeAndData(blockposition, blockpumpkin.getBlockData(), 3); + } + + itemstack.subtract(1); + } else { + ItemStack itemstack1 = ItemArmor.a(isourceblock, itemstack); + + if (itemstack1.isEmpty()) { + this.b = false; + } + } + + return itemstack; + } + }); + EnumColor[] aenumcolor = EnumColor.values(); + int i = aenumcolor.length; + + for (int j = 0; j < i; ++j) { + EnumColor enumcolor = aenumcolor[j]; + + BlockDispenser.REGISTRY.a(Item.getItemOf(BlockShulkerBox.a(enumcolor)), new DispenserRegistry.c(null)); + } + + } + + public static void c() { + if (!DispenserRegistry.c) { + DispenserRegistry.c = true; + d(); + SoundEffect.b(); + Block.w(); + BlockFire.e(); + MobEffectList.k(); + Enchantment.g(); + Item.t(); + PotionRegistry.b(); + PotionBrewer.a(); + EntityTypes.c(); + BiomeBase.q(); + b(); + if (!CraftingManager.init()) { + DispenserRegistry.b = true; + DispenserRegistry.d.error("Errors with built-in recipes!"); + } + + StatisticList.a(); + if (DispenserRegistry.d.isDebugEnabled()) { + if ((new AdvancementDataWorld((File) null)).b()) { + DispenserRegistry.b = true; + DispenserRegistry.d.error("Errors with built-in advancements!"); + } + + if (!LootTables.b()) { + DispenserRegistry.b = true; + DispenserRegistry.d.error("Errors with built-in loot tables"); + } + } + + } + } + + private static void d() { + if (DispenserRegistry.d.isDebugEnabled()) { + System.setErr(new DebugOutputStream("STDERR", System.err)); + System.setOut(new DebugOutputStream("STDOUT", DispenserRegistry.a)); + } else { + System.setErr(new RedirectStream("STDERR", System.err)); + System.setOut(new RedirectStream("STDOUT", DispenserRegistry.a)); + } + + } + + static class c extends DispenserRegistry.b { + + private c() {} + + protected ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + Block block = Block.asBlock(itemstack.getItem()); + World world = isourceblock.getWorld(); + EnumDirection enumdirection = (EnumDirection) isourceblock.e().get(BlockDispenser.FACING); + BlockPosition blockposition = isourceblock.getBlockPosition().shift(enumdirection); + + // CraftBukkit start + org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + // CraftBukkit end + + this.b = world.a(block, blockposition, false, EnumDirection.DOWN, (Entity) null); + if (this.b) { + EnumDirection enumdirection1 = world.isEmpty(blockposition.down()) ? enumdirection : EnumDirection.UP; + IBlockData iblockdata = block.getBlockData().set(BlockShulkerBox.a, enumdirection1); + // Dionysus start - fix Dispenser crashes + boolean wasPlaced = world.setTypeUpdate(blockposition, iblockdata); + if (!wasPlaced) { + return itemstack; + } + // Dionysus end + TileEntity tileentity = world.getTileEntity(blockposition); + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + + if (itemstack1.hasTag()) { + ((TileEntityShulkerBox) tileentity).e(itemstack1.getTag().getCompound("BlockEntityTag")); + } + + if (itemstack1.hasName()) { + ((TileEntityShulkerBox) tileentity).setCustomName(itemstack1.getName()); + } + + world.updateAdjacentComparators(blockposition, iblockdata.getBlock()); + } + + return itemstack; + } + + c(Object object) { + this(); + } + } + + public abstract static class b extends DispenseBehaviorItem { + + protected boolean b = true; + + public b() {} + + protected void a(ISourceBlock isourceblock) { + isourceblock.getWorld().triggerEffect(this.b ? 1000 : 1001, isourceblock.getBlockPosition(), 0); + } + } + + public static class a extends DispenseBehaviorItem { + + private final DispenseBehaviorItem b = new DispenseBehaviorItem(); + private final EntityBoat.EnumBoatType c; + + public a(EntityBoat.EnumBoatType entityboat_enumboattype) { + this.c = entityboat_enumboattype; + } + + public ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + EnumDirection enumdirection = (EnumDirection) isourceblock.e().get(BlockDispenser.FACING); + World world = isourceblock.getWorld(); + double d0 = isourceblock.getX() + (double) ((float) enumdirection.getAdjacentX() * 1.125F); + double d1 = isourceblock.getY() + (double) ((float) enumdirection.getAdjacentY() * 1.125F); + double d2 = isourceblock.getZ() + (double) ((float) enumdirection.getAdjacentZ() * 1.125F); + BlockPosition blockposition = isourceblock.getBlockPosition().shift(enumdirection); + Material material = world.getType(blockposition).getMaterial(); + double d3; + + if (Material.WATER.equals(material)) { + d3 = 1.0D; + } else { + if (!Material.AIR.equals(material) || !Material.WATER.equals(world.getType(blockposition.down()).getMaterial())) { + return this.b.a(isourceblock, itemstack); + } + + d3 = 0.0D; + } + + // EntityBoat entityboat = new EntityBoat(world, d0, d1 + d3, d2); + // CraftBukkit start + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1 + d3, d2)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.add(1); + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.add(1); + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + + EntityBoat entityboat = new EntityBoat(world, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ()); + // CraftBukkit end + + entityboat.setType(this.c); + entityboat.yaw = enumdirection.l(); + if (!world.addEntity(entityboat)) itemstack.add(1); // CraftBukkit + // itemstack.subtract(1); // CraftBukkit - handled during event processing + return itemstack; + } + + protected void a(ISourceBlock isourceblock) { + isourceblock.getWorld().triggerEffect(1000, isourceblock.getBlockPosition(), 0); + } + } +}