--- ../src-base/minecraft/net/minecraftforge/common/ForgeHooks.java +++ ../src-work/minecraft/net/minecraftforge/common/ForgeHooks.java @@ -63,6 +63,16 @@ import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.NoteBlockEvent; import static net.minecraft.init.Blocks.*; +// Cauldron start +import net.minecraftforge.common.util.FakePlayer; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.TreeType; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.block.CraftBlockState; +import org.bukkit.entity.Player; +import org.bukkit.event.world.StructureGrowEvent; +//Cauldron end public class ForgeHooks { @@ -379,10 +389,12 @@ public static ChatComponentTranslation onServerChatEvent(NetHandlerPlayServer net, String raw, ChatComponentTranslation comp) { ServerChatEvent event = new ServerChatEvent(net.playerEntity, raw, comp); + synchronized (ServerChatEvent.class) { if (MinecraftForge.EVENT_BUS.post(event)) { return null; } + } return event.component; } @@ -439,6 +451,8 @@ public static BlockEvent.BreakEvent onBlockBreakEvent(World world, GameType gameType, EntityPlayerMP entityPlayer, int x, int y, int z) { + // Cauldron - pre-cancel handled in BreakEvent + /* // Logic from tryHarvestBlock for pre-canceling the event boolean preCancelEvent = false; if (gameType.isAdventure() && !entityPlayer.isCurrentToolAdventureModeExempt(x, y, z)) @@ -449,9 +463,9 @@ { preCancelEvent = true; } - + */ // Tell client the block is gone immediately then process events - if (world.getTileEntity(x, y, z) == null) + if (world.getTileEntity(x, y, z) == null && !(entityPlayer instanceof FakePlayer)) // Cauldron - don't send packets to fakeplayers { S23PacketBlockChange packet = new S23PacketBlockChange(x, y, z, world); packet.field_148883_d = Blocks.air; @@ -463,11 +477,11 @@ Block block = world.getBlock(x, y, z); int blockMetadata = world.getBlockMetadata(x, y, z); BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(x, y, z, world, block, blockMetadata, entityPlayer); - event.setCanceled(preCancelEvent); + // event.setCanceled(preCancelEvent); // Cauldron MinecraftForge.EVENT_BUS.post(event); // Handle if the event is canceled - if (event.isCanceled()) + if (event.isCanceled() && !(entityPlayer instanceof FakePlayer)) // Cauldron - don't send packets to fakeplayers { // Let the client know the block still exists entityPlayer.playerNetServerHandler.sendPacket(new S23PacketBlockChange(x, y, z, world)); @@ -500,81 +514,157 @@ if (!(itemstack.getItem() instanceof ItemBucket)) // if not bucket { world.captureBlockSnapshots = true; + // Cauldron start + if (itemstack.getItem() instanceof net.minecraft.item.ItemDye && itemstack.getItemDamage() == 15) + { + Block block = world.getBlock(x, y, z); + if (block != null && (block instanceof net.minecraft.block.BlockSapling || block instanceof net.minecraft.block.BlockMushroom)) + { + world.captureTreeGeneration = true; + } + } + // Cauldron end } + ItemStack.currentPlayer = player; // Cauldron boolean flag = itemstack.getItem().onItemUse(itemstack, player, world, x, y, z, side, hitX, hitY, hitZ); + ItemStack.currentPlayer = null; // Cauldron world.captureBlockSnapshots = false; - if (flag) + // Cauldron start + if (flag && world.captureTreeGeneration && world.capturedBlockSnapshots.size() > 0) { - // save new item data - int newMeta = itemstack.getItemDamage(); - int newSize = itemstack.stackSize; - NBTTagCompound newNBT = null; - if (itemstack.getTagCompound() != null) + world.captureTreeGeneration = false; + Location loc = new Location(world.getWorld(), (double) x, (double) y, (double) z); + TreeType type = net.minecraft.block.BlockSapling.treeType; + net.minecraft.block.BlockSapling.treeType = null; + List states = new ArrayList(); + + for (net.minecraftforge.common.util.BlockSnapshot snapshot : (List) world.capturedBlockSnapshots.clone()) { - newNBT = (NBTTagCompound)itemstack.getTagCompound().copy(); + states.add(new CraftBlockState(snapshot)); } - net.minecraftforge.event.world.BlockEvent.PlaceEvent placeEvent = null; - List blockSnapshots = (List) world.capturedBlockSnapshots.clone(); - world.capturedBlockSnapshots.clear(); - // make sure to set pre-placement item data for event - itemstack.setItemDamage(meta); - itemstack.stackSize = size; - if (nbt != null) + world.capturedBlockSnapshots.clear(); + StructureGrowEvent event = null; + if (type != null) { - itemstack.setTagCompound(nbt); + event = new StructureGrowEvent(loc, type, false, (Player) player.getBukkitEntity(), states); + Bukkit.getPluginManager().callEvent(event); } - if (blockSnapshots.size() > 1) - { - placeEvent = ForgeEventFactory.onPlayerMultiBlockPlace(player, blockSnapshots, net.minecraftforge.common.util.ForgeDirection.getOrientation(side)); - } - else if (blockSnapshots.size() == 1) - { - placeEvent = ForgeEventFactory.onPlayerBlockPlace(player, blockSnapshots.get(0), net.minecraftforge.common.util.ForgeDirection.getOrientation(side)); - } - if (placeEvent != null && (placeEvent.isCanceled())) + if (event == null || !event.isCancelled()) { - flag = false; // cancel placement - // revert back all captured blocks - for (net.minecraftforge.common.util.BlockSnapshot blocksnapshot : blockSnapshots) + for (BlockState state : states) { - world.restoringBlockSnapshots = true; - blocksnapshot.restore(true, false); - world.restoringBlockSnapshots = false; + state.update(true); } } - else + + return flag; + } + else + { + world.captureTreeGeneration = false; // Cauldron end + if (flag) { - // Change the stack to its new content - itemstack.setItemDamage(newMeta); - itemstack.stackSize = newSize; + // save new item data + int newMeta = itemstack.getItemDamage(); + int newSize = itemstack.stackSize; + NBTTagCompound newNBT = null; + if (itemstack.getTagCompound() != null) + { + newNBT = (NBTTagCompound) itemstack.getTagCompound().copy(); + } + net.minecraftforge.event.world.BlockEvent.PlaceEvent placeEvent = null; + List blockSnapshots = (List) world.capturedBlockSnapshots + .clone(); + world.capturedBlockSnapshots.clear(); + List tDropItemSnapshots=(List)world.capturedEntitySnapshots.clone(); + world.capturedEntitySnapshots.clear(); + List tCaptureItems=(List)world.capturedItems.clone(); + world.capturedItems.clear(); + + // make sure to set pre-placement item data for event + itemstack.setItemDamage(meta); + itemstack.stackSize = size; if (nbt != null) { - itemstack.setTagCompound(newNBT); + itemstack.setTagCompound(nbt); } + if (blockSnapshots.size() > 1) + { + placeEvent = ForgeEventFactory.onPlayerMultiBlockPlace(player, blockSnapshots, + net.minecraftforge.common.util.ForgeDirection.getOrientation(side)); + } + else if (blockSnapshots.size() == 1) + { + placeEvent = ForgeEventFactory.onPlayerBlockPlace(player, blockSnapshots.get(0), + net.minecraftforge.common.util.ForgeDirection.getOrientation(side)); + } - for (net.minecraftforge.common.util.BlockSnapshot blocksnapshot : blockSnapshots) + if (placeEvent != null && (placeEvent.isCanceled())) { - int blockX = blocksnapshot.x; - int blockY = blocksnapshot.y; - int blockZ = blocksnapshot.z; - int metadata = world.getBlockMetadata(blockX, blockY, blockZ); - int updateFlag = blocksnapshot.flag; - Block oldBlock = blocksnapshot.replacedBlock; - Block newBlock = world.getBlock(blockX, blockY, blockZ); - if (newBlock != null && !(newBlock.hasTileEntity(metadata))) // Containers get placed automatically + flag = false; // cancel placement + // revert back all captured blocks + for(int i=blockSnapshots.size();i>0;){ + world.restoringBlockSnapshots=true; + blockSnapshots.get(--i).restore(true,false); + world.restoringBlockSnapshots=false; + } + for(net.minecraftforge.common.util.EntitySnapshot sEntityItem : tDropItemSnapshots){ + sEntityItem.cancel(); + } + } + else + { + // Change the stack to its new content + itemstack.setItemDamage(newMeta); + itemstack.stackSize = newSize; + if (nbt != null) { - newBlock.onBlockAdded(world, blockX, blockY, blockZ); + itemstack.setTagCompound(newNBT); } - world.markAndNotifyBlock(blockX, blockY, blockZ, null, oldBlock, newBlock, updateFlag); + for (net.minecraftforge.common.util.BlockSnapshot blocksnapshot : blockSnapshots) + { + int blockX = blocksnapshot.x; + int blockY = blocksnapshot.y; + int blockZ = blocksnapshot.z; + int metadata = world.getBlockMetadata(blockX, blockY, blockZ); + int updateFlag = blocksnapshot.flag; + Block oldBlock = blocksnapshot.replacedBlock; + Block newBlock = world.getBlock(blockX, blockY, blockZ); + if (newBlock != null && !(newBlock.hasTileEntity(metadata))) // Containers + // get + // placed + // automatically + { + newBlock.onBlockAdded(world, blockX, blockY, blockZ); + } + + world.markAndNotifyBlock(blockX, blockY, blockZ, null, oldBlock, newBlock, updateFlag); + } + for(net.minecraftforge.common.util.EntitySnapshot sEntityItem : tDropItemSnapshots){ + sEntityItem.apply(); + } + if(!tCaptureItems.isEmpty()){ + boolean tAdded=false; + for(ItemStack sItem : tCaptureItems){ + if(!player.inventory.addItemStackToInventory(sItem)){ + world.spawnEntityInWorld(new EntityItem(world,player.posX,player.posY,player.posZ,sItem)); + }else{ + tAdded=true; + } + } + if(tAdded) player.openContainer.detectAndSendChanges(); + } + player.addStat(StatList.objectUseStats[Item.getIdFromItem(itemstack.getItem())], 1); } - player.addStat(StatList.objectUseStats[Item.getIdFromItem(itemstack.getItem())], 1); + } } + world.capturedBlockSnapshots.clear(); return flag;