package net.minecraft.block;
import cpw.mods.fml.common.registry.GameData;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import net.minecraft.block.material.MapColor;
import net.minecraft.block.material.Material;
import net.minecraft.client.particle.EffectRenderer;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.entity.boss.EntityDragon;
import net.minecraft.entity.boss.EntityWither;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.item.EntityXPOrb;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.StatList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntitySign;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.IIcon;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.RegistryNamespaced;
import net.minecraft.util.RegistryNamespacedDefaultedByKey;
import net.minecraft.util.StatCollector;
import net.minecraft.util.Vec3;
import net.minecraft.world.Explosion;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraft.world.WorldProviderEnd;
import net.minecraftforge.common.EnumPlantType;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.common.IPlantable;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.common.util.RotationHelper;
import net.minecraftforge.event.ForgeEventFactory;
import static net.minecraftforge.common.util.ForgeDirection.*;
public class Block
{
public static final RegistryNamespaced blockRegistry = GameData.getBlockRegistry();
private CreativeTabs displayOnCreativeTab;
protected String textureName;
public static final Block.SoundType soundTypeStone = new Block.SoundType("stone", 1.0F, 1.0F);
/** the wood sound type */
public static final Block.SoundType soundTypeWood = new Block.SoundType("wood", 1.0F, 1.0F);
/** the gravel sound type */
public static final Block.SoundType soundTypeGravel = new Block.SoundType("gravel", 1.0F, 1.0F);
public static final Block.SoundType soundTypeGrass = new Block.SoundType("grass", 1.0F, 1.0F);
public static final Block.SoundType soundTypePiston = new Block.SoundType("stone", 1.0F, 1.0F);
public static final Block.SoundType soundTypeMetal = new Block.SoundType("stone", 1.0F, 1.5F);
public static final Block.SoundType soundTypeGlass = new Block.SoundType("stone", 1.0F, 1.0F)
{
private static final String __OBFID = "CL_00000200";
public String getDigResourcePath()
{
return "dig.glass";
}
public String getPlaceSound()
{
return "step.stone";
}
};
public static final Block.SoundType soundTypeCloth = new Block.SoundType("cloth", 1.0F, 1.0F);
public static final Block.SoundType soundTypeSand = new Block.SoundType("sand", 1.0F, 1.0F);
public static final Block.SoundType soundTypeSnow = new Block.SoundType("snow", 1.0F, 1.0F);
public static final Block.SoundType soundTypeLadder = new Block.SoundType("ladder", 1.0F, 1.0F)
{
private static final String __OBFID = "CL_00000201";
public String getDigResourcePath()
{
return "dig.wood";
}
};
public static final Block.SoundType soundTypeAnvil = new Block.SoundType("anvil", 0.3F, 1.0F)
{
private static final String __OBFID = "CL_00000202";
public String getDigResourcePath()
{
return "dig.stone";
}
public String getPlaceSound()
{
return "random.anvil_land";
}
};
protected boolean fullBlock;
/** How much light is subtracted for going through this block */
protected int lightOpacity;
protected boolean translucent;
/** Amount of light emitted */
protected int lightValue;
/** Flag if block should use the brightest neighbor light value as its own */
protected boolean useNeighborBrightness;
/** Indicates how many hits it takes to break a block. */
protected float blockHardness;
protected float blockResistance;
protected boolean blockConstructorCalled = true;
protected boolean enableStats = true;
/**
* Flags whether or not this block is of a type that needs random ticking. Ref-counted by ExtendedBlockStorage in
* order to broadly cull a chunk from the random chunk update list for efficiency's sake.
*/
protected boolean needsRandomTick;
/** true if the Block contains a Tile Entity */
protected boolean isBlockContainer;
protected double minX;
protected double minY;
protected double minZ;
protected double maxX;
protected double maxY;
protected double maxZ;
/** Sound of stepping on the block */
public Block.SoundType stepSound;
public float blockParticleGravity;
protected final Material blockMaterial;
/** Determines how much velocity is maintained while moving on top of this block */
public float slipperiness;
private String unlocalizedName;
@SideOnly(Side.CLIENT)
protected IIcon blockIcon;
private static final String __OBFID = "CL_00000199";
public final cpw.mods.fml.common.registry.RegistryDelegate<Block> delegate =
((cpw.mods.fml.common.registry.FMLControlledNamespacedRegistry)blockRegistry).getDelegate(this, Block.class);
public static int getIdFromBlock(Block blockIn)
{
return blockRegistry.getIDForObject(blockIn);
}
public static Block getBlockById(int id)
{
Block ret = (Block)blockRegistry.getObjectById(id);
return ret == null ? Blocks.air : ret;
}
public static Block getBlockFromItem(Item itemIn)
{
return getBlockById(Item.getIdFromItem(itemIn));
}
public static Block getBlockFromName(String name)
{
if (blockRegistry.containsKey(name))
{
return (Block)blockRegistry.getObject(name);
}
else
{
try
{
return (Block)blockRegistry.getObjectById(Integer.parseInt(name));
}
catch (NumberFormatException numberformatexception)
{
return null;
}
}
}
public boolean isFullBlock()
{
return this.fullBlock;
}
public int getLightOpacity()
{
return this.lightOpacity;
}
@SideOnly(Side.CLIENT)
public boolean isTranslucent()
{
return this.translucent;
}
public int getLightValue()
{
return this.lightValue;
}
/**
* Should block use the brightest neighbor light value as its own
*/
public boolean getUseNeighborBrightness()
{
return this.useNeighborBrightness;
}
/**
* Get a material of block
*/
public Material getMaterial()
{
return this.blockMaterial;
}
public MapColor getMapColor(int meta)
{
return this.getMaterial().getMaterialMapColor();
}
public static void registerBlocks()
{
blockRegistry.addObject(0, "air", (new BlockAir()).setUnlocalizedName("air"));
blockRegistry.addObject(1, "stone", (new BlockStone()).setHardness(1.5F).setResistance(10.0F).setStepSound(soundTypePiston).setUnlocalizedName("stone").setTextureName("stone"));
blockRegistry.addObject(2, "grass", (new BlockGrass()).setHardness(0.6F).setStepSound(soundTypeGrass).setUnlocalizedName("grass").setTextureName("grass"));
blockRegistry.addObject(3, "dirt", (new BlockDirt()).setHardness(0.5F).setStepSound(soundTypeGravel).setUnlocalizedName("dirt").setTextureName("dirt"));
Block block = (new Block(Material.rock)).setHardness(2.0F).setResistance(10.0F).setStepSound(soundTypePiston).setUnlocalizedName("stonebrick").setCreativeTab(CreativeTabs.tabBlock).setTextureName("cobblestone");
blockRegistry.addObject(4, "cobblestone", block);
Block block1 = (new BlockWood()).setHardness(2.0F).setResistance(5.0F).setStepSound(soundTypeWood).setUnlocalizedName("wood").setTextureName("planks");
blockRegistry.addObject(5, "planks", block1);
blockRegistry.addObject(6, "sapling", (new BlockSapling()).setHardness(0.0F).setStepSound(soundTypeGrass).setUnlocalizedName("sapling").setTextureName("sapling"));
blockRegistry.addObject(7, "bedrock", (new Block(Material.rock)).setBlockUnbreakable().setResistance(6000000.0F).setStepSound(soundTypePiston).setUnlocalizedName("bedrock").disableStats().setCreativeTab(CreativeTabs.tabBlock).setTextureName("bedrock"));
blockRegistry.addObject(8, "flowing_water", (new BlockDynamicLiquid(Material.water)).setHardness(100.0F).setLightOpacity(3).setUnlocalizedName("water").disableStats().setTextureName("water_flow"));
blockRegistry.addObject(9, "water", (new BlockStaticLiquid(Material.water)).setHardness(100.0F).setLightOpacity(3).setUnlocalizedName("water").disableStats().setTextureName("water_still"));
blockRegistry.addObject(10, "flowing_lava", (new BlockDynamicLiquid(Material.lava)).setHardness(100.0F).setLightLevel(1.0F).setUnlocalizedName("lava").disableStats().setTextureName("lava_flow"));
blockRegistry.addObject(11, "lava", (new BlockStaticLiquid(Material.lava)).setHardness(100.0F).setLightLevel(1.0F).setUnlocalizedName("lava").disableStats().setTextureName("lava_still"));
blockRegistry.addObject(12, "sand", (new BlockSand()).setHardness(0.5F).setStepSound(soundTypeSand).setUnlocalizedName("sand").setTextureName("sand"));
blockRegistry.addObject(13, "gravel", (new BlockGravel()).setHardness(0.6F).setStepSound(soundTypeGravel).setUnlocalizedName("gravel").setTextureName("gravel"));
blockRegistry.addObject(14, "gold_ore", (new BlockOre()).setHardness(3.0F).setResistance(5.0F).setStepSound(soundTypePiston).setUnlocalizedName("oreGold").setTextureName("gold_ore"));
blockRegistry.addObject(15, "iron_ore", (new BlockOre()).setHardness(3.0F).setResistance(5.0F).setStepSound(soundTypePiston).setUnlocalizedName("oreIron").setTextureName("iron_ore"));
blockRegistry.addObject(16, "coal_ore", (new BlockOre()).setHardness(3.0F).setResistance(5.0F).setStepSound(soundTypePiston).setUnlocalizedName("oreCoal").setTextureName("coal_ore"));
blockRegistry.addObject(17, "log", (new BlockOldLog()).setUnlocalizedName("log").setTextureName("log"));
blockRegistry.addObject(18, "leaves", (new BlockOldLeaf()).setUnlocalizedName("leaves").setTextureName("leaves"));
blockRegistry.addObject(19, "sponge", (new BlockSponge()).setHardness(0.6F).setStepSound(soundTypeGrass).setUnlocalizedName("sponge").setTextureName("sponge"));
blockRegistry.addObject(20, "glass", (new BlockGlass(Material.glass, false)).setHardness(0.3F).setStepSound(soundTypeGlass).setUnlocalizedName("glass").setTextureName("glass"));
blockRegistry.addObject(21, "lapis_ore", (new BlockOre()).setHardness(3.0F).setResistance(5.0F).setStepSound(soundTypePiston).setUnlocalizedName("oreLapis").setTextureName("lapis_ore"));
blockRegistry.addObject(22, "lapis_block", (new BlockCompressed(MapColor.lapisColor)).setHardness(3.0F).setResistance(5.0F).setStepSound(soundTypePiston).setUnlocalizedName("blockLapis").setCreativeTab(CreativeTabs.tabBlock).setTextureName("lapis_block"));
blockRegistry.addObject(23, "dispenser", (new BlockDispenser()).setHardness(3.5F).setStepSound(soundTypePiston).setUnlocalizedName("dispenser").setTextureName("dispenser"));
Block block2 = (new BlockSandStone()).setStepSound(soundTypePiston).setHardness(0.8F).setUnlocalizedName("sandStone").setTextureName("sandstone");
blockRegistry.addObject(24, "sandstone", block2);
blockRegistry.addObject(25, "noteblock", (new BlockNote()).setHardness(0.8F).setUnlocalizedName("musicBlock").setTextureName("noteblock"));
blockRegistry.addObject(26, "bed", (new BlockBed()).setHardness(0.2F).setUnlocalizedName("bed").disableStats().setTextureName("bed"));
blockRegistry.addObject(27, "golden_rail", (new BlockRailPowered()).setHardness(0.7F).setStepSound(soundTypeMetal).setUnlocalizedName("goldenRail").setTextureName("rail_golden"));
blockRegistry.addObject(28, "detector_rail", (new BlockRailDetector()).setHardness(0.7F).setStepSound(soundTypeMetal).setUnlocalizedName("detectorRail").setTextureName("rail_detector"));
blockRegistry.addObject(29, "sticky_piston", (new BlockPistonBase(true)).setUnlocalizedName("pistonStickyBase"));
blockRegistry.addObject(30, "web", (new BlockWeb()).setLightOpacity(1).setHardness(4.0F).setUnlocalizedName("web").setTextureName("web"));
blockRegistry.addObject(31, "tallgrass", (new BlockTallGrass()).setHardness(0.0F).setStepSound(soundTypeGrass).setUnlocalizedName("tallgrass"));
blockRegistry.addObject(32, "deadbush", (new BlockDeadBush()).setHardness(0.0F).setStepSound(soundTypeGrass).setUnlocalizedName("deadbush").setTextureName("deadbush"));
blockRegistry.addObject(33, "piston", (new BlockPistonBase(false)).setUnlocalizedName("pistonBase"));
blockRegistry.addObject(34, "piston_head", new BlockPistonExtension());
blockRegistry.addObject(35, "wool", (new BlockColored(Material.cloth)).setHardness(0.8F).setStepSound(soundTypeCloth).setUnlocalizedName("cloth").setTextureName("wool_colored"));
blockRegistry.addObject(36, "piston_extension", new BlockPistonMoving());
blockRegistry.addObject(37, "yellow_flower", (new BlockFlower(0)).setHardness(0.0F).setStepSound(soundTypeGrass).setUnlocalizedName("flower1").setTextureName("flower_dandelion"));
blockRegistry.addObject(38, "red_flower", (new BlockFlower(1)).setHardness(0.0F).setStepSound(soundTypeGrass).setUnlocalizedName("flower2").setTextureName("flower_rose"));
blockRegistry.addObject(39, "brown_mushroom", (new BlockMushroom()).setHardness(0.0F).setStepSound(soundTypeGrass).setLightLevel(0.125F).setUnlocalizedName("mushroom").setTextureName("mushroom_brown"));
blockRegistry.addObject(40, "red_mushroom", (new BlockMushroom()).setHardness(0.0F).setStepSound(soundTypeGrass).setUnlocalizedName("mushroom").setTextureName("mushroom_red"));
blockRegistry.addObject(41, "gold_block", (new BlockCompressed(MapColor.goldColor)).setHardness(3.0F).setResistance(10.0F).setStepSound(soundTypeMetal).setUnlocalizedName("blockGold").setTextureName("gold_block"));
blockRegistry.addObject(42, "iron_block", (new BlockCompressed(MapColor.ironColor)).setHardness(5.0F).setResistance(10.0F).setStepSound(soundTypeMetal).setUnlocalizedName("blockIron").setTextureName("iron_block"));
blockRegistry.addObject(43, "double_stone_slab", (new BlockStoneSlab(true)).setHardness(2.0F).setResistance(10.0F).setStepSound(soundTypePiston).setUnlocalizedName("stoneSlab"));
blockRegistry.addObject(44, "stone_slab", (new BlockStoneSlab(false)).setHardness(2.0F).setResistance(10.0F).setStepSound(soundTypePiston).setUnlocalizedName("stoneSlab"));
Block block3 = (new Block(Material.rock)).setHardness(2.0F).setResistance(10.0F).setStepSound(soundTypePiston).setUnlocalizedName("brick").setCreativeTab(CreativeTabs.tabBlock).setTextureName("brick");
blockRegistry.addObject(45, "brick_block", block3);
blockRegistry.addObject(46, "tnt", (new BlockTNT()).setHardness(0.0F).setStepSound(soundTypeGrass).setUnlocalizedName("tnt").setTextureName("tnt"));
blockRegistry.addObject(47, "bookshelf", (new BlockBookshelf()).setHardness(1.5F).setStepSound(soundTypeWood).setUnlocalizedName("bookshelf").setTextureName("bookshelf"));
blockRegistry.addObject(48, "mossy_cobblestone", (new Block(Material.rock)).setHardness(2.0F).setResistance(10.0F).setStepSound(soundTypePiston).setUnlocalizedName("stoneMoss").setCreativeTab(CreativeTabs.tabBlock).setTextureName("cobblestone_mossy"));
blockRegistry.addObject(49, "obsidian", (new BlockObsidian()).setHardness(50.0F).setResistance(2000.0F).setStepSound(soundTypePiston).setUnlocalizedName("obsidian").setTextureName("obsidian"));
blockRegistry.addObject(50, "torch", (new BlockTorch()).setHardness(0.0F).setLightLevel(0.9375F).setStepSound(soundTypeWood).setUnlocalizedName("torch").setTextureName("torch_on"));
blockRegistry.addObject(51, "fire", (new BlockFire()).setHardness(0.0F).setLightLevel(1.0F).setStepSound(soundTypeWood).setUnlocalizedName("fire").disableStats().setTextureName("fire"));
blockRegistry.addObject(52, "mob_spawner", (new BlockMobSpawner()).setHardness(5.0F).setStepSound(soundTypeMetal).setUnlocalizedName("mobSpawner").disableStats().setTextureName("mob_spawner"));
blockRegistry.addObject(53, "oak_stairs", (new BlockStairs(block1, 0)).setUnlocalizedName("stairsWood"));
blockRegistry.addObject(54, "chest", (new BlockChest(0)).setHardness(2.5F).setStepSound(soundTypeWood).setUnlocalizedName("chest"));
blockRegistry.addObject(55, "redstone_wire", (new BlockRedstoneWire()).setHardness(0.0F).setStepSound(soundTypeStone).setUnlocalizedName("redstoneDust").disableStats().setTextureName("redstone_dust"));
blockRegistry.addObject(56, "diamond_ore", (new BlockOre()).setHardness(3.0F).setResistance(5.0F).setStepSound(soundTypePiston).setUnlocalizedName("oreDiamond").setTextureName("diamond_ore"));
blockRegistry.addObject(57, "diamond_block", (new BlockCompressed(MapColor.diamondColor)).setHardness(5.0F).setResistance(10.0F).setStepSound(soundTypeMetal).setUnlocalizedName("blockDiamond").setTextureName("diamond_block"));
blockRegistry.addObject(58, "crafting_table", (new BlockWorkbench()).setHardness(2.5F).setStepSound(soundTypeWood).setUnlocalizedName("workbench").setTextureName("crafting_table"));
blockRegistry.addObject(59, "wheat", (new BlockCrops()).setUnlocalizedName("crops").setTextureName("wheat"));
Block block4 = (new BlockFarmland()).setHardness(0.6F).setStepSound(soundTypeGravel).setUnlocalizedName("farmland").setTextureName("farmland");
blockRegistry.addObject(60, "farmland", block4);
blockRegistry.addObject(61, "furnace", (new BlockFurnace(false)).setHardness(3.5F).setStepSound(soundTypePiston).setUnlocalizedName("furnace").setCreativeTab(CreativeTabs.tabDecorations));
blockRegistry.addObject(62, "lit_furnace", (new BlockFurnace(true)).setHardness(3.5F).setStepSound(soundTypePiston).setLightLevel(0.875F).setUnlocalizedName("furnace"));
blockRegistry.addObject(63, "standing_sign", (new BlockSign(TileEntitySign.class, true)).setHardness(1.0F).setStepSound(soundTypeWood).setUnlocalizedName("sign").disableStats());
blockRegistry.addObject(64, "wooden_door", (new BlockDoor(Material.wood)).setHardness(3.0F).setStepSound(soundTypeWood).setUnlocalizedName("doorWood").disableStats().setTextureName("door_wood"));
blockRegistry.addObject(65, "ladder", (new BlockLadder()).setHardness(0.4F).setStepSound(soundTypeLadder).setUnlocalizedName("ladder").setTextureName("ladder"));
blockRegistry.addObject(66, "rail", (new BlockRail()).setHardness(0.7F).setStepSound(soundTypeMetal).setUnlocalizedName("rail").setTextureName("rail_normal"));
blockRegistry.addObject(67, "stone_stairs", (new BlockStairs(block, 0)).setUnlocalizedName("stairsStone"));
blockRegistry.addObject(68, "wall_sign", (new BlockSign(TileEntitySign.class, false)).setHardness(1.0F).setStepSound(soundTypeWood).setUnlocalizedName("sign").disableStats());
blockRegistry.addObject(69, "lever", (new BlockLever()).setHardness(0.5F).setStepSound(soundTypeWood).setUnlocalizedName("lever").setTextureName("lever"));
blockRegistry.addObject(70, "stone_pressure_plate", (new BlockPressurePlate("stone", Material.rock, BlockPressurePlate.Sensitivity.mobs)).setHardness(0.5F).setStepSound(soundTypePiston).setUnlocalizedName("pressurePlate"));
blockRegistry.addObject(71, "iron_door", (new BlockDoor(Material.iron)).setHardness(5.0F).setStepSound(soundTypeMetal).setUnlocalizedName("doorIron").disableStats().setTextureName("door_iron"));
blockRegistry.addObject(72, "wooden_pressure_plate", (new BlockPressurePlate("planks_oak", Material.wood, BlockPressurePlate.Sensitivity.everything)).setHardness(0.5F).setStepSound(soundTypeWood).setUnlocalizedName("pressurePlate"));
blockRegistry.addObject(73, "redstone_ore", (new BlockRedstoneOre(false)).setHardness(3.0F).setResistance(5.0F).setStepSound(soundTypePiston).setUnlocalizedName("oreRedstone").setCreativeTab(CreativeTabs.tabBlock).setTextureName("redstone_ore"));
blockRegistry.addObject(74, "lit_redstone_ore", (new BlockRedstoneOre(true)).setLightLevel(0.625F).setHardness(3.0F).setResistance(5.0F).setStepSound(soundTypePiston).setUnlocalizedName("oreRedstone").setTextureName("redstone_ore"));
blockRegistry.addObject(75, "unlit_redstone_torch", (new BlockRedstoneTorch(false)).setHardness(0.0F).setStepSound(soundTypeWood).setUnlocalizedName("notGate").setTextureName("redstone_torch_off"));
blockRegistry.addObject(76, "redstone_torch", (new BlockRedstoneTorch(true)).setHardness(0.0F).setLightLevel(0.5F).setStepSound(soundTypeWood).setUnlocalizedName("notGate").setCreativeTab(CreativeTabs.tabRedstone).setTextureName("redstone_torch_on"));
blockRegistry.addObject(77, "stone_button", (new BlockButtonStone()).setHardness(0.5F).setStepSound(soundTypePiston).setUnlocalizedName("button"));
blockRegistry.addObject(78, "snow_layer", (new BlockSnow()).setHardness(0.1F).setStepSound(soundTypeSnow).setUnlocalizedName("snow").setLightOpacity(0).setTextureName("snow"));
blockRegistry.addObject(79, "ice", (new BlockIce()).setHardness(0.5F).setLightOpacity(3).setStepSound(soundTypeGlass).setUnlocalizedName("ice").setTextureName("ice"));
blockRegistry.addObject(80, "snow", (new BlockSnowBlock()).setHardness(0.2F).setStepSound(soundTypeSnow).setUnlocalizedName("snow").setTextureName("snow"));
blockRegistry.addObject(81, "cactus", (new BlockCactus()).setHardness(0.4F).setStepSound(soundTypeCloth).setUnlocalizedName("cactus").setTextureName("cactus"));
blockRegistry.addObject(82, "clay", (new BlockClay()).setHardness(0.6F).setStepSound(soundTypeGravel).setUnlocalizedName("clay").setTextureName("clay"));
blockRegistry.addObject(83, "reeds", (new BlockReed()).setHardness(0.0F).setStepSound(soundTypeGrass).setUnlocalizedName("reeds").disableStats().setTextureName("reeds"));
blockRegistry.addObject(84, "jukebox", (new BlockJukebox()).setHardness(2.0F).setResistance(10.0F).setStepSound(soundTypePiston).setUnlocalizedName("jukebox").setTextureName("jukebox"));
blockRegistry.addObject(85, "fence", (new BlockFence("planks_oak", Material.wood)).setHardness(2.0F).setResistance(5.0F).setStepSound(soundTypeWood).setUnlocalizedName("fence"));
Block block5 = (new BlockPumpkin(false)).setHardness(1.0F).setStepSound(soundTypeWood).setUnlocalizedName("pumpkin").setTextureName("pumpkin");
blockRegistry.addObject(86, "pumpkin", block5);
blockRegistry.addObject(87, "netherrack", (new BlockNetherrack()).setHardness(0.4F).setStepSound(soundTypePiston).setUnlocalizedName("hellrock").setTextureName("netherrack"));
blockRegistry.addObject(88, "soul_sand", (new BlockSoulSand()).setHardness(0.5F).setStepSound(soundTypeSand).setUnlocalizedName("hellsand").setTextureName("soul_sand"));
blockRegistry.addObject(89, "glowstone", (new BlockGlowstone(Material.glass)).setHardness(0.3F).setStepSound(soundTypeGlass).setLightLevel(1.0F).setUnlocalizedName("lightgem").setTextureName("glowstone"));
blockRegistry.addObject(90, "portal", (new BlockPortal()).setHardness(-1.0F).setStepSound(soundTypeGlass).setLightLevel(0.75F).setUnlocalizedName("portal").setTextureName("portal"));
blockRegistry.addObject(91, "lit_pumpkin", (new BlockPumpkin(true)).setHardness(1.0F).setStepSound(soundTypeWood).setLightLevel(1.0F).setUnlocalizedName("litpumpkin").setTextureName("pumpkin"));
blockRegistry.addObject(92, "cake", (new BlockCake()).setHardness(0.5F).setStepSound(soundTypeCloth).setUnlocalizedName("cake").disableStats().setTextureName("cake"));
blockRegistry.addObject(93, "unpowered_repeater", (new BlockRedstoneRepeater(false)).setHardness(0.0F).setStepSound(soundTypeWood).setUnlocalizedName("diode").disableStats().setTextureName("repeater_off"));
blockRegistry.addObject(94, "powered_repeater", (new BlockRedstoneRepeater(true)).setHardness(0.0F).setLightLevel(0.625F).setStepSound(soundTypeWood).setUnlocalizedName("diode").disableStats().setTextureName("repeater_on"));
blockRegistry.addObject(95, "stained_glass", (new BlockStainedGlass(Material.glass)).setHardness(0.3F).setStepSound(soundTypeGlass).setUnlocalizedName("stainedGlass").setTextureName("glass"));
blockRegistry.addObject(96, "trapdoor", (new BlockTrapDoor(Material.wood)).setHardness(3.0F).setStepSound(soundTypeWood).setUnlocalizedName("trapdoor").disableStats().setTextureName("trapdoor"));
blockRegistry.addObject(97, "monster_egg", (new BlockSilverfish()).setHardness(0.75F).setUnlocalizedName("monsterStoneEgg"));
Block block6 = (new BlockStoneBrick()).setHardness(1.5F).setResistance(10.0F).setStepSound(soundTypePiston).setUnlocalizedName("stonebricksmooth").setTextureName("stonebrick");
blockRegistry.addObject(98, "stonebrick", block6);
blockRegistry.addObject(99, "brown_mushroom_block", (new BlockHugeMushroom(Material.wood, 0)).setHardness(0.2F).setStepSound(soundTypeWood).setUnlocalizedName("mushroom").setTextureName("mushroom_block"));
blockRegistry.addObject(100, "red_mushroom_block", (new BlockHugeMushroom(Material.wood, 1)).setHardness(0.2F).setStepSound(soundTypeWood).setUnlocalizedName("mushroom").setTextureName("mushroom_block"));
blockRegistry.addObject(101, "iron_bars", (new BlockPane("iron_bars", "iron_bars", Material.iron, true)).setHardness(5.0F).setResistance(10.0F).setStepSound(soundTypeMetal).setUnlocalizedName("fenceIron"));
blockRegistry.addObject(102, "glass_pane", (new BlockPane("glass", "glass_pane_top", Material.glass, false)).setHardness(0.3F).setStepSound(soundTypeGlass).setUnlocalizedName("thinGlass"));
Block block7 = (new BlockMelon()).setHardness(1.0F).setStepSound(soundTypeWood).setUnlocalizedName("melon").setTextureName("melon");
blockRegistry.addObject(103, "melon_block", block7);
blockRegistry.addObject(104, "pumpkin_stem", (new BlockStem(block5)).setHardness(0.0F).setStepSound(soundTypeWood).setUnlocalizedName("pumpkinStem").setTextureName("pumpkin_stem"));
blockRegistry.addObject(105, "melon_stem", (new BlockStem(block7)).setHardness(0.0F).setStepSound(soundTypeWood).setUnlocalizedName("pumpkinStem").setTextureName("melon_stem"));
blockRegistry.addObject(106, "vine", (new BlockVine()).setHardness(0.2F).setStepSound(soundTypeGrass).setUnlocalizedName("vine").setTextureName("vine"));
blockRegistry.addObject(107, "fence_gate", (new BlockFenceGate()).setHardness(2.0F).setResistance(5.0F).setStepSound(soundTypeWood).setUnlocalizedName("fenceGate"));
blockRegistry.addObject(108, "brick_stairs", (new BlockStairs(block3, 0)).setUnlocalizedName("stairsBrick"));
blockRegistry.addObject(109, "stone_brick_stairs", (new BlockStairs(block6, 0)).setUnlocalizedName("stairsStoneBrickSmooth"));
blockRegistry.addObject(110, "mycelium", (new BlockMycelium()).setHardness(0.6F).setStepSound(soundTypeGrass).setUnlocalizedName("mycel").setTextureName("mycelium"));
blockRegistry.addObject(111, "waterlily", (new BlockLilyPad()).setHardness(0.0F).setStepSound(soundTypeGrass).setUnlocalizedName("waterlily").setTextureName("waterlily"));
Block block8 = (new Block(Material.rock)).setHardness(2.0F).setResistance(10.0F).setStepSound(soundTypePiston).setUnlocalizedName("netherBrick").setCreativeTab(CreativeTabs.tabBlock).setTextureName("nether_brick");
blockRegistry.addObject(112, "nether_brick", block8);
blockRegistry.addObject(113, "nether_brick_fence", (new BlockFence("nether_brick", Material.rock)).setHardness(2.0F).setResistance(10.0F).setStepSound(soundTypePiston).setUnlocalizedName("netherFence"));
blockRegistry.addObject(114, "nether_brick_stairs", (new BlockStairs(block8, 0)).setUnlocalizedName("stairsNetherBrick"));
blockRegistry.addObject(115, "nether_wart", (new BlockNetherWart()).setUnlocalizedName("netherStalk").setTextureName("nether_wart"));
blockRegistry.addObject(116, "enchanting_table", (new BlockEnchantmentTable()).setHardness(5.0F).setResistance(2000.0F).setUnlocalizedName("enchantmentTable").setTextureName("enchanting_table"));
blockRegistry.addObject(117, "brewing_stand", (new BlockBrewingStand()).setHardness(0.5F).setLightLevel(0.125F).setUnlocalizedName("brewingStand").setTextureName("brewing_stand"));
blockRegistry.addObject(118, "cauldron", (new BlockCauldron()).setHardness(2.0F).setUnlocalizedName("cauldron").setTextureName("cauldron"));
blockRegistry.addObject(119, "end_portal", (new BlockEndPortal(Material.portal)).setHardness(-1.0F).setResistance(6000000.0F));
blockRegistry.addObject(120, "end_portal_frame", (new BlockEndPortalFrame()).setStepSound(soundTypeGlass).setLightLevel(0.125F).setHardness(-1.0F).setUnlocalizedName("endPortalFrame").setResistance(6000000.0F).setCreativeTab(CreativeTabs.tabDecorations).setTextureName("endframe"));
blockRegistry.addObject(121, "end_stone", (new Block(Material.rock)).setHardness(3.0F).setResistance(15.0F).setStepSound(soundTypePiston).setUnlocalizedName("whiteStone").setCreativeTab(CreativeTabs.tabBlock).setTextureName("end_stone"));
blockRegistry.addObject(122, "dragon_egg", (new BlockDragonEgg()).setHardness(3.0F).setResistance(15.0F).setStepSound(soundTypePiston).setLightLevel(0.125F).setUnlocalizedName("dragonEgg").setTextureName("dragon_egg"));
blockRegistry.addObject(123, "redstone_lamp", (new BlockRedstoneLight(false)).setHardness(0.3F).setStepSound(soundTypeGlass).setUnlocalizedName("redstoneLight").setCreativeTab(CreativeTabs.tabRedstone).setTextureName("redstone_lamp_off"));
blockRegistry.addObject(124, "lit_redstone_lamp", (new BlockRedstoneLight(true)).setHardness(0.3F).setStepSound(soundTypeGlass).setUnlocalizedName("redstoneLight").setTextureName("redstone_lamp_on"));
blockRegistry.addObject(125, "double_wooden_slab", (new BlockWoodSlab(true)).setHardness(2.0F).setResistance(5.0F).setStepSound(soundTypeWood).setUnlocalizedName("woodSlab"));
blockRegistry.addObject(126, "wooden_slab", (new BlockWoodSlab(false)).setHardness(2.0F).setResistance(5.0F).setStepSound(soundTypeWood).setUnlocalizedName("woodSlab"));
blockRegistry.addObject(127, "cocoa", (new BlockCocoa()).setHardness(0.2F).setResistance(5.0F).setStepSound(soundTypeWood).setUnlocalizedName("cocoa").setTextureName("cocoa"));
blockRegistry.addObject(128, "sandstone_stairs", (new BlockStairs(block2, 0)).setUnlocalizedName("stairsSandStone"));
blockRegistry.addObject(129, "emerald_ore", (new BlockOre()).setHardness(3.0F).setResistance(5.0F).setStepSound(soundTypePiston).setUnlocalizedName("oreEmerald").setTextureName("emerald_ore"));
blockRegistry.addObject(130, "ender_chest", (new BlockEnderChest()).setHardness(22.5F).setResistance(1000.0F).setStepSound(soundTypePiston).setUnlocalizedName("enderChest").setLightLevel(0.5F));
blockRegistry.addObject(131, "tripwire_hook", (new BlockTripWireHook()).setUnlocalizedName("tripWireSource").setTextureName("trip_wire_source"));
blockRegistry.addObject(132, "tripwire", (new BlockTripWire()).setUnlocalizedName("tripWire").setTextureName("trip_wire"));
blockRegistry.addObject(133, "emerald_block", (new BlockCompressed(MapColor.emeraldColor)).setHardness(5.0F).setResistance(10.0F).setStepSound(soundTypeMetal).setUnlocalizedName("blockEmerald").setTextureName("emerald_block"));
blockRegistry.addObject(134, "spruce_stairs", (new BlockStairs(block1, 1)).setUnlocalizedName("stairsWoodSpruce"));
blockRegistry.addObject(135, "birch_stairs", (new BlockStairs(block1, 2)).setUnlocalizedName("stairsWoodBirch"));
blockRegistry.addObject(136, "jungle_stairs", (new BlockStairs(block1, 3)).setUnlocalizedName("stairsWoodJungle"));
blockRegistry.addObject(137, "command_block", (new BlockCommandBlock()).setBlockUnbreakable().setResistance(6000000.0F).setUnlocalizedName("commandBlock").setTextureName("command_block"));
blockRegistry.addObject(138, "beacon", (new BlockBeacon()).setUnlocalizedName("beacon").setLightLevel(1.0F).setTextureName("beacon"));
blockRegistry.addObject(139, "cobblestone_wall", (new BlockWall(block)).setUnlocalizedName("cobbleWall"));
blockRegistry.addObject(140, "flower_pot", (new BlockFlowerPot()).setHardness(0.0F).setStepSound(soundTypeStone).setUnlocalizedName("flowerPot").setTextureName("flower_pot"));
blockRegistry.addObject(141, "carrots", (new BlockCarrot()).setUnlocalizedName("carrots").setTextureName("carrots"));
blockRegistry.addObject(142, "potatoes", (new BlockPotato()).setUnlocalizedName("potatoes").setTextureName("potatoes"));
blockRegistry.addObject(143, "wooden_button", (new BlockButtonWood()).setHardness(0.5F).setStepSound(soundTypeWood).setUnlocalizedName("button"));
blockRegistry.addObject(144, "skull", (new BlockSkull()).setHardness(1.0F).setStepSound(soundTypePiston).setUnlocalizedName("skull").setTextureName("skull"));
blockRegistry.addObject(145, "anvil", (new BlockAnvil()).setHardness(5.0F).setStepSound(soundTypeAnvil).setResistance(2000.0F).setUnlocalizedName("anvil"));
blockRegistry.addObject(146, "trapped_chest", (new BlockChest(1)).setHardness(2.5F).setStepSound(soundTypeWood).setUnlocalizedName("chestTrap"));
blockRegistry.addObject(147, "light_weighted_pressure_plate", (new BlockPressurePlateWeighted("gold_block", Material.iron, 15)).setHardness(0.5F).setStepSound(soundTypeWood).setUnlocalizedName("weightedPlate_light"));
blockRegistry.addObject(148, "heavy_weighted_pressure_plate", (new BlockPressurePlateWeighted("iron_block", Material.iron, 150)).setHardness(0.5F).setStepSound(soundTypeWood).setUnlocalizedName("weightedPlate_heavy"));
blockRegistry.addObject(149, "unpowered_comparator", (new BlockRedstoneComparator(false)).setHardness(0.0F).setStepSound(soundTypeWood).setUnlocalizedName("comparator").disableStats().setTextureName("comparator_off"));
blockRegistry.addObject(150, "powered_comparator", (new BlockRedstoneComparator(true)).setHardness(0.0F).setLightLevel(0.625F).setStepSound(soundTypeWood).setUnlocalizedName("comparator").disableStats().setTextureName("comparator_on"));
blockRegistry.addObject(151, "daylight_detector", (new BlockDaylightDetector()).setHardness(0.2F).setStepSound(soundTypeWood).setUnlocalizedName("daylightDetector").setTextureName("daylight_detector"));
blockRegistry.addObject(152, "redstone_block", (new BlockCompressedPowered(MapColor.tntColor)).setHardness(5.0F).setResistance(10.0F).setStepSound(soundTypeMetal).setUnlocalizedName("blockRedstone").setTextureName("redstone_block"));
blockRegistry.addObject(153, "quartz_ore", (new BlockOre()).setHardness(3.0F).setResistance(5.0F).setStepSound(soundTypePiston).setUnlocalizedName("netherquartz").setTextureName("quartz_ore"));
blockRegistry.addObject(154, "hopper", (new BlockHopper()).setHardness(3.0F).setResistance(8.0F).setStepSound(soundTypeWood).setUnlocalizedName("hopper").setTextureName("hopper"));
Block block9 = (new BlockQuartz()).setStepSound(soundTypePiston).setHardness(0.8F).setUnlocalizedName("quartzBlock").setTextureName("quartz_block");
blockRegistry.addObject(155, "quartz_block", block9);
blockRegistry.addObject(156, "quartz_stairs", (new BlockStairs(block9, 0)).setUnlocalizedName("stairsQuartz"));
blockRegistry.addObject(157, "activator_rail", (new BlockRailPowered()).setHardness(0.7F).setStepSound(soundTypeMetal).setUnlocalizedName("activatorRail").setTextureName("rail_activator"));
blockRegistry.addObject(158, "dropper", (new BlockDropper()).setHardness(3.5F).setStepSound(soundTypePiston).setUnlocalizedName("dropper").setTextureName("dropper"));
blockRegistry.addObject(159, "stained_hardened_clay", (new BlockColored(Material.rock)).setHardness(1.25F).setResistance(7.0F).setStepSound(soundTypePiston).setUnlocalizedName("clayHardenedStained").setTextureName("hardened_clay_stained"));
blockRegistry.addObject(160, "stained_glass_pane", (new BlockStainedGlassPane()).setHardness(0.3F).setStepSound(soundTypeGlass).setUnlocalizedName("thinStainedGlass").setTextureName("glass"));
blockRegistry.addObject(161, "leaves2", (new BlockNewLeaf()).setUnlocalizedName("leaves").setTextureName("leaves"));
blockRegistry.addObject(162, "log2", (new BlockNewLog()).setUnlocalizedName("log").setTextureName("log"));
blockRegistry.addObject(163, "acacia_stairs", (new BlockStairs(block1, 4)).setUnlocalizedName("stairsWoodAcacia"));
blockRegistry.addObject(164, "dark_oak_stairs", (new BlockStairs(block1, 5)).setUnlocalizedName("stairsWoodDarkOak"));
blockRegistry.addObject(170, "hay_block", (new BlockHay()).setHardness(0.5F).setStepSound(soundTypeGrass).setUnlocalizedName("hayBlock").setCreativeTab(CreativeTabs.tabBlock).setTextureName("hay_block"));
blockRegistry.addObject(171, "carpet", (new BlockCarpet()).setHardness(0.1F).setStepSound(soundTypeCloth).setUnlocalizedName("woolCarpet").setLightOpacity(0));
blockRegistry.addObject(172, "hardened_clay", (new BlockHardenedClay()).setHardness(1.25F).setResistance(7.0F).setStepSound(soundTypePiston).setUnlocalizedName("clayHardened").setTextureName("hardened_clay"));
blockRegistry.addObject(173, "coal_block", (new Block(Material.rock)).setHardness(5.0F).setResistance(10.0F).setStepSound(soundTypePiston).setUnlocalizedName("blockCoal").setCreativeTab(CreativeTabs.tabBlock).setTextureName("coal_block"));
blockRegistry.addObject(174, "packed_ice", (new BlockPackedIce()).setHardness(0.5F).setStepSound(soundTypeGlass).setUnlocalizedName("icePacked").setTextureName("ice_packed"));
blockRegistry.addObject(175, "double_plant", new BlockDoublePlant());
Iterator iterator = blockRegistry.iterator();
while (iterator.hasNext())
{
Block block10 = (Block)iterator.next();
if (block10.blockMaterial == Material.air)
{
block10.useNeighborBrightness = false;
}
else
{
boolean flag = false;
boolean flag1 = block10.getRenderType() == 10;
boolean flag2 = block10 instanceof BlockSlab;
boolean flag3 = block10 == block4;
boolean flag4 = block10.translucent;
boolean flag5 = block10.lightOpacity == 0;
if (flag1 || flag2 || flag3 || flag4 || flag5)
{
flag = true;
}
block10.useNeighborBrightness = flag;
}
}
}
protected Block(Material materialIn)
{
this.stepSound = soundTypeStone;
this.blockParticleGravity = 1.0F;
this.slipperiness = 0.6F;
this.blockMaterial = materialIn;
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
this.fullBlock = this.isOpaqueCube();
this.lightOpacity = this.isOpaqueCube() ? 255 : 0;
this.translucent = !materialIn.blocksLight();
}
/**
* Sets the footstep sound for the block. Returns the object for convenience in constructing.
*/
public Block setStepSound(Block.SoundType sound)
{
this.stepSound = sound;
return this;
}
/**
* Sets how much light is blocked going through this block. Returns the object for convenience in constructing.
*/
public Block setLightOpacity(int opacity)
{
this.lightOpacity = opacity;
return this;
}
/**
* Sets the light value that the block emits. Returns resulting block instance for constructing convenience. Args:
* level
*/
public Block setLightLevel(float value)
{
this.lightValue = (int)(15.0F * value);
return this;
}
/**
* Sets the the blocks resistance to explosions. Returns the object for convenience in constructing.
*/
public Block setResistance(float resistance)
{
this.blockResistance = resistance * 3.0F;
return this;
}
/**
* Indicate if a material is a normal solid opaque cube
*/
@SideOnly(Side.CLIENT)
public boolean isBlockNormalCube()
{
return this.blockMaterial.blocksMovement() && this.renderAsNormalBlock();
}
public boolean isNormalCube()
{
return this.blockMaterial.isOpaque() && this.renderAsNormalBlock() && !this.canProvidePower();
}
public boolean renderAsNormalBlock()
{
return true;
}
public boolean isPassable(IBlockAccess worldIn, int x, int y, int z)
{
return !this.blockMaterial.blocksMovement();
}
/**
* The type of render function that is called for this block
*/
public int getRenderType()
{
return 0;
}
/**
* Sets how many hits it takes to break a block.
*/
public Block setHardness(float hardness)
{
this.blockHardness = hardness;
if (this.blockResistance < hardness * 5.0F)
{
this.blockResistance = hardness * 5.0F;
}
return this;
}
public Block setBlockUnbreakable()
{
this.setHardness(-1.0F);
return this;
}
public float getBlockHardness(World worldIn, int x, int y, int z)
{
return this.blockHardness;
}
/**
* Sets whether this block type will receive random update ticks
*/
public Block setTickRandomly(boolean shouldTick)
{
this.needsRandomTick = shouldTick;
return this;
}
/**
* Returns whether or not this block is of a type that needs random ticking. Called for ref-counting purposes by
* ExtendedBlockStorage in order to broadly cull a chunk from the random chunk update list for efficiency's sake.
*/
public boolean getTickRandomly()
{
return this.needsRandomTick;
}
@Deprecated //Forge: New Metadata sensitive version.
public boolean hasTileEntity()
{
return hasTileEntity(0);
}
public final void setBlockBounds(float minX, float minY, float minZ, float maxX, float maxY, float maxZ)
{
this.minX = (double)minX;
this.minY = (double)minY;
this.minZ = (double)minZ;
this.maxX = (double)maxX;
this.maxY = (double)maxY;
this.maxZ = (double)maxZ;
}
/**
* How bright to render this block based on the light its receiving. Args: iBlockAccess, x, y, z
*/
@SideOnly(Side.CLIENT)
public int getMixedBrightnessForBlock(IBlockAccess worldIn, int x, int y, int z)
{
Block block = worldIn.getBlock(x, y, z);
int l = worldIn.getLightBrightnessForSkyBlocks(x, y, z, block.getLightValue(worldIn, x, y, z));
if (l == 0 && block instanceof BlockSlab)
{
--y;
block = worldIn.getBlock(x, y, z);
return worldIn.getLightBrightnessForSkyBlocks(x, y, z, block.getLightValue(worldIn, x, y, z));
}
else
{
return l;
}
}
/**
* Returns true if the given side of this block type should be rendered, if the adjacent block is at the given
* coordinates. Args: blockAccess, x, y, z, side
*/
@SideOnly(Side.CLIENT)
public boolean shouldSideBeRendered(IBlockAccess worldIn, int x, int y, int z, int side)
{
return side == 0 && this.minY > 0.0D ? true : (side == 1 && this.maxY < 1.0D ? true : (side == 2 && this.minZ > 0.0D ? true : (side == 3 && this.maxZ < 1.0D ? true : (side == 4 && this.minX > 0.0D ? true : (side == 5 && this.maxX < 1.0D ? true : !worldIn.getBlock(x, y, z).isOpaqueCube())))));
}
public boolean isBlockSolid(IBlockAccess worldIn, int x, int y, int z, int side)
{
return worldIn.getBlock(x, y, z).getMaterial().isSolid();
}
@SideOnly(Side.CLIENT)
public IIcon getIcon(IBlockAccess worldIn, int x, int y, int z, int side)
{
return this.getIcon(side, worldIn.getBlockMetadata(x, y, z));
}
/**
* Gets the block's texture. Args: side, meta
*/
@SideOnly(Side.CLIENT)
public IIcon getIcon(int side, int meta)
{
return this.blockIcon;
}
public void addCollisionBoxesToList(World worldIn, int x, int y, int z, AxisAlignedBB mask, List list, Entity collider)
{
AxisAlignedBB axisalignedbb1 = this.getCollisionBoundingBoxFromPool(worldIn, x, y, z);
if (axisalignedbb1 != null && mask.intersectsWith(axisalignedbb1))
{
list.add(axisalignedbb1);
}
}
/**
* Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
* cleared to be reused)
*/
public AxisAlignedBB getCollisionBoundingBoxFromPool(World worldIn, int x, int y, int z)
{
return AxisAlignedBB.getBoundingBox((double)x + this.minX, (double)y + this.minY, (double)z + this.minZ, (double)x + this.maxX, (double)y + this.maxY, (double)z + this.maxZ);
}
/**
* Returns the block texture based on the side being looked at. Args: side
*/
@SideOnly(Side.CLIENT)
public final IIcon getBlockTextureFromSide(int side)
{
return this.getIcon(side, 0);
}
/**
* Returns the bounding box of the wired rectangular prism to render.
*/
@SideOnly(Side.CLIENT)
public AxisAlignedBB getSelectedBoundingBoxFromPool(World worldIn, int x, int y, int z)
{
return AxisAlignedBB.getBoundingBox((double)x + this.minX, (double)y + this.minY, (double)z + this.minZ, (double)x + this.maxX, (double)y + this.maxY, (double)z + this.maxZ);
}
public boolean isOpaqueCube()
{
return true;
}
/**
* Returns whether the raytracing must ignore this block. Args : metadata, stopOnLiquid
*/
public boolean canStopRayTrace(int meta, boolean includeLiquid)
{
return this.isCollidable();
}
/**
* Returns if this block is collidable (only used by Fire). Args: x, y, z
*/
public boolean isCollidable()
{
return true;
}
/**
* Ticks the block if it's been scheduled
*/
public void updateTick(World worldIn, int x, int y, int z, Random random) {}
/**
* A randomly called display update to be able to add particles or other items for display
*/
@SideOnly(Side.CLIENT)
public void randomDisplayTick(World worldIn, int x, int y, int z, Random random) {}
public void onBlockDestroyedByPlayer(World worldIn, int x, int y, int z, int meta) {}
public void onNeighborBlockChange(World worldIn, int x, int y, int z, Block neighbor) {}
/**
* How many world ticks before ticking
*/
public int tickRate(World worldIn)
{
return 10;
}
public void onBlockAdded(World worldIn, int x, int y, int z) {}
public void breakBlock(World worldIn, int x, int y, int z, Block blockBroken, int meta)
{
if (hasTileEntity(meta) && !(this instanceof BlockContainer))
{
worldIn.removeTileEntity(x, y, z);
}
}
/**
* Returns the quantity of items to drop on block destruction.
*/
public int quantityDropped(Random random)
{
return 1;
}
public Item getItemDropped(int meta, Random random, int fortune)
{
return Item.getItemFromBlock(this);
}
public float getPlayerRelativeBlockHardness(EntityPlayer player, World worldIn, int x, int y, int z)
{
return ForgeHooks.blockStrength(this, player, worldIn, x, y, z);
}
/**
* Drops the specified block items
*/
public final void dropBlockAsItem(World worldIn, int x, int y, int z, int meta, int fortune)
{
this.dropBlockAsItemWithChance(worldIn, x, y, z, meta, 1.0F, fortune);
}
/**
* Drops the block items with a specified chance of dropping the specified items
*/
public void dropBlockAsItemWithChance(World worldIn, int x, int y, int z, int meta, float chance, int fortune)
{
if (!worldIn.isRemote && !worldIn.restoringBlockSnapshots) // do not drop items while restoring blockstates, prevents item dupe
{
ArrayList<ItemStack> items = getDrops(worldIn, x, y, z, meta, fortune);
chance = ForgeEventFactory.fireBlockHarvesting(items, worldIn, this, x, y, z, meta, fortune, chance, false, harvesters.get());
for (ItemStack item : items)
{
if (worldIn.rand.nextFloat() <= chance)
{
this.dropBlockAsItem(worldIn, x, y, z, item);
}
}
}
}
/**
* Spawns EntityItem in the world for the given ItemStack if the world is not remote.
*/
protected void dropBlockAsItem(World worldIn, int x, int y, int z, ItemStack itemIn)
{
if (!worldIn.isRemote && worldIn.getGameRules().getGameRuleBooleanValue("doTileDrops") && !worldIn.restoringBlockSnapshots) // do not drop items while restoring blockstates, prevents item dupe
{
if (captureDrops.get())
{
capturedDrops.get().add(itemIn);
return;
}
float f = 0.7F;
double d0 = (double)(worldIn.rand.nextFloat() * f) + (double)(1.0F - f) * 0.5D;
double d1 = (double)(worldIn.rand.nextFloat() * f) + (double)(1.0F - f) * 0.5D;
double d2 = (double)(worldIn.rand.nextFloat() * f) + (double)(1.0F - f) * 0.5D;
EntityItem entityitem = new EntityItem(worldIn, (double)x + d0, (double)y + d1, (double)z + d2, itemIn);
entityitem.delayBeforeCanPickup = 10;
worldIn.spawnEntityInWorld(entityitem);
}
}
public void dropXpOnBlockBreak(World worldIn, int x, int y, int z, int amount)
{
if (!worldIn.isRemote)
{
while (amount > 0)
{
int i1 = EntityXPOrb.getXPSplit(amount);
amount -= i1;
worldIn.spawnEntityInWorld(new EntityXPOrb(worldIn, (double)x + 0.5D, (double)y + 0.5D, (double)z + 0.5D, i1));
}
}
}
/**
* Determines the damage on the item the block drops. Used in cloth and wood.
*/
public int damageDropped(int meta)
{
return 0;
}
/**
* Returns how much this block can resist explosions from the passed in entity.
*/
public float getExplosionResistance(Entity exploder)
{
return this.blockResistance / 5.0F;
}
public MovingObjectPosition collisionRayTrace(World worldIn, int x, int y, int z, Vec3 startVec, Vec3 endVec)
{
this.setBlockBoundsBasedOnState(worldIn, x, y, z);
startVec = startVec.addVector((double)(-x), (double)(-y), (double)(-z));
endVec = endVec.addVector((double)(-x), (double)(-y), (double)(-z));
Vec3 vec32 = startVec.getIntermediateWithXValue(endVec, this.minX);
Vec3 vec33 = startVec.getIntermediateWithXValue(endVec, this.maxX);
Vec3 vec34 = startVec.getIntermediateWithYValue(endVec, this.minY);
Vec3 vec35 = startVec.getIntermediateWithYValue(endVec, this.maxY);
Vec3 vec36 = startVec.getIntermediateWithZValue(endVec, this.minZ);
Vec3 vec37 = startVec.getIntermediateWithZValue(endVec, this.maxZ);
if (!this.isVecInsideYZBounds(vec32))
{
vec32 = null;
}
if (!this.isVecInsideYZBounds(vec33))
{
vec33 = null;
}
if (!this.isVecInsideXZBounds(vec34))
{
vec34 = null;
}
if (!this.isVecInsideXZBounds(vec35))
{
vec35 = null;
}
if (!this.isVecInsideXYBounds(vec36))
{
vec36 = null;
}
if (!this.isVecInsideXYBounds(vec37))
{
vec37 = null;
}
Vec3 vec38 = null;
if (vec32 != null && (vec38 == null || startVec.squareDistanceTo(vec32) < startVec.squareDistanceTo(vec38)))
{
vec38 = vec32;
}
if (vec33 != null && (vec38 == null || startVec.squareDistanceTo(vec33) < startVec.squareDistanceTo(vec38)))
{
vec38 = vec33;
}
if (vec34 != null && (vec38 == null || startVec.squareDistanceTo(vec34) < startVec.squareDistanceTo(vec38)))
{
vec38 = vec34;
}
if (vec35 != null && (vec38 == null || startVec.squareDistanceTo(vec35) < startVec.squareDistanceTo(vec38)))
{
vec38 = vec35;
}
if (vec36 != null && (vec38 == null || startVec.squareDistanceTo(vec36) < startVec.squareDistanceTo(vec38)))
{
vec38 = vec36;
}
if (vec37 != null && (vec38 == null || startVec.squareDistanceTo(vec37) < startVec.squareDistanceTo(vec38)))
{
vec38 = vec37;
}
if (vec38 == null)
{
return null;
}
else
{
byte b0 = -1;
if (vec38 == vec32)
{
b0 = 4;
}
if (vec38 == vec33)
{
b0 = 5;
}
if (vec38 == vec34)
{
b0 = 0;
}
if (vec38 == vec35)
{
b0 = 1;
}
if (vec38 == vec36)
{
b0 = 2;
}
if (vec38 == vec37)
{
b0 = 3;
}
return new MovingObjectPosition(x, y, z, b0, vec38.addVector((double)x, (double)y, (double)z));
}
}
/**
* Checks if a vector is within the Y and Z bounds of the block.
*/
private boolean isVecInsideYZBounds(Vec3 point)
{
return point == null ? false : point.yCoord >= this.minY && point.yCoord <= this.maxY && point.zCoord >= this.minZ && point.zCoord <= this.maxZ;
}
/**
* Checks if a vector is within the X and Z bounds of the block.
*/
private boolean isVecInsideXZBounds(Vec3 point)
{
return point == null ? false : point.xCoord >= this.minX && point.xCoord <= this.maxX && point.zCoord >= this.minZ && point.zCoord <= this.maxZ;
}
/**
* Checks if a vector is within the X and Y bounds of the block.
*/
private boolean isVecInsideXYBounds(Vec3 point)
{
return point == null ? false : point.xCoord >= this.minX && point.xCoord <= this.maxX && point.yCoord >= this.minY && point.yCoord <= this.maxY;
}
/**
* Called upon the block being destroyed by an explosion
*/
public void onBlockDestroyedByExplosion(World worldIn, int x, int y, int z, Explosion explosionIn) {}
public boolean canReplace(World worldIn, int x, int y, int z, int side, ItemStack itemIn)
{
return this.canPlaceBlockOnSide(worldIn, x, y, z, side);
}
/**
* Returns which pass should this block be rendered on. 0 for solids and 1 for alpha
*/
@SideOnly(Side.CLIENT)
public int getRenderBlockPass()
{
return 0;
}
/**
* checks to see if you can place this block can be placed on that side of a block: BlockLever overrides
*/
public boolean canPlaceBlockOnSide(World worldIn, int x, int y, int z, int side)
{
return this.canPlaceBlockAt(worldIn, x, y, z);
}
public boolean canPlaceBlockAt(World worldIn, int x, int y, int z)
{
return worldIn.getBlock(x, y, z).isReplaceable(worldIn, x, y, z);
}
/**
* Called upon block activation (right click on the block). Args : world, x, y, z, player, side, hitX, hitY, hitZ.
* Return : Swing hand (client), abort the block placement (server)
*/
public boolean onBlockActivated(World worldIn, int x, int y, int z, EntityPlayer player, int side, float subX, float subY, float subZ)
{
return false;
}
public void onEntityWalking(World worldIn, int x, int y, int z, Entity entityIn) {}
public int onBlockPlaced(World worldIn, int x, int y, int z, int side, float subX, float subY, float subZ, int meta)
{
return meta;
}
/**
* Called when a player hits the block. Args: world, x, y, z, player
*/
public void onBlockClicked(World worldIn, int x, int y, int z, EntityPlayer player) {}
public void modifyEntityVelocity(World worldIn, int x, int y, int z, Entity entityIn, Vec3 velocity) {}
public void setBlockBoundsBasedOnState(IBlockAccess worldIn, int x, int y, int z) {}
/**
* returns the block bounderies minX value
*/
public final double getBlockBoundsMinX()
{
return this.minX;
}
/**
* returns the block bounderies maxX value
*/
public final double getBlockBoundsMaxX()
{
return this.maxX;
}
/**
* returns the block bounderies minY value
*/
public final double getBlockBoundsMinY()
{
return this.minY;
}
/**
* returns the block bounderies maxY value
*/
public final double getBlockBoundsMaxY()
{
return this.maxY;
}
/**
* returns the block bounderies minZ value
*/
public final double getBlockBoundsMinZ()
{
return this.minZ;
}
/**
* returns the block bounderies maxZ value
*/
public final double getBlockBoundsMaxZ()
{
return this.maxZ;
}
@SideOnly(Side.CLIENT)
public int getBlockColor()
{
return 16777215;
}
/**
* Returns the color this block should be rendered. Used by leaves.
*/
@SideOnly(Side.CLIENT)
public int getRenderColor(int meta)
{
return 16777215;
}
/**
* Returns a integer with hex for 0xrrggbb with this color multiplied against the blocks color. Note only called
* when first determining what to render.
*/
@SideOnly(Side.CLIENT)
public int colorMultiplier(IBlockAccess worldIn, int x, int y, int z)
{
return 16777215;
}
public int isProvidingWeakPower(IBlockAccess worldIn, int x, int y, int z, int side)
{
return 0;
}
/**
* Can this block provide power. Only wire currently seems to have this change based on its state.
*/
public boolean canProvidePower()
{
return false;
}
public void onEntityCollidedWithBlock(World worldIn, int x, int y, int z, Entity entityIn) {}
public int isProvidingStrongPower(IBlockAccess worldIn, int x, int y, int z, int side)
{
return 0;
}
/**
* Sets the block's bounds for rendering it as an item
*/
public void setBlockBoundsForItemRender() {}
public void harvestBlock(World worldIn, EntityPlayer player, int x, int y, int z, int meta)
{
player.addStat(StatList.mineBlockStatArray[getIdFromBlock(this)], 1);
player.addExhaustion(0.025F);
if (this.canSilkHarvest(worldIn, player, x, y, z, meta) && EnchantmentHelper.getSilkTouchModifier(player))
{
ArrayList<ItemStack> items = new ArrayList<ItemStack>();
ItemStack itemstack = this.createStackedBlock(meta);
if (itemstack != null)
{
items.add(itemstack);
}
ForgeEventFactory.fireBlockHarvesting(items, worldIn, this, x, y, z, meta, 0, 1.0f, true, player);
for (ItemStack is : items)
{
this.dropBlockAsItem(worldIn, x, y, z, is);
}
}
else
{
harvesters.set(player);
int i1 = EnchantmentHelper.getFortuneModifier(player);
this.dropBlockAsItem(worldIn, x, y, z, meta, i1);
harvesters.set(null);
}
}
protected boolean canSilkHarvest()
{
Integer meta = silk_check_meta.get();
return this.renderAsNormalBlock() && !this.hasTileEntity(meta == null ? 0 : meta);
}
/**
* Returns an item stack containing a single instance of the current block type. 'i' is the block's subtype/damage
* and is ignored for blocks which do not support subtypes. Blocks which cannot be harvested should return null.
*/
protected ItemStack createStackedBlock(int meta)
{
int j = 0;
Item item = Item.getItemFromBlock(this);
if (item != null && item.getHasSubtypes())
{
j = meta;
}
return new ItemStack(item, 1, j);
}
/**
* Returns the usual quantity dropped by the block plus a bonus of 1 to 'i' (inclusive).
*/
public int quantityDroppedWithBonus(int maxBonus, Random random)
{
return this.quantityDropped(random);
}
/**
* Can this block stay at this position. Similar to canPlaceBlockAt except gets checked often with plants.
*/
public boolean canBlockStay(World worldIn, int x, int y, int z)
{
return true;
}
/**
* Called when the block is placed in the world.
*/
public void onBlockPlacedBy(World worldIn, int x, int y, int z, EntityLivingBase placer, ItemStack itemIn) {}
/**
* Called after a block is placed
*/
public void onPostBlockPlaced(World worldIn, int x, int y, int z, int meta) {}
public Block setUnlocalizedName(String name)
{
this.unlocalizedName = name;
return this;
}
/**
* Gets the localized name of this block. Used for the statistics page.
*/
public String getLocalizedName()
{
return StatCollector.translateToLocal(this.getUnlocalizedName() + ".name");
}
/**
* Returns the unlocalized name of the block with "tile." appended to the front.
*/
public String getUnlocalizedName()
{
return "tile." + this.unlocalizedName;
}
public boolean onBlockEventReceived(World worldIn, int x, int y, int z, int eventId, int eventData)
{
return false;
}
/**
* Return the state of blocks statistics flags - if the block is counted for mined and placed.
*/
public boolean getEnableStats()
{
return this.enableStats;
}
protected Block disableStats()
{
this.enableStats = false;
return this;
}
public int getMobilityFlag()
{
return this.blockMaterial.getMaterialMobility();
}
/**
* Returns the default ambient occlusion value based on block opacity
*/
@SideOnly(Side.CLIENT)
public float getAmbientOcclusionLightValue()
{
return this.isBlockNormalCube() ? 0.2F : 1.0F;
}
/**
* Block's chance to react to an entity falling on it.
*/
public void onFallenUpon(World worldIn, int x, int y, int z, Entity entityIn, float fallDistance) {}
/**
* Gets an item for the block being called on. Args: world, x, y, z
*/
@SideOnly(Side.CLIENT)
public Item getItem(World worldIn, int x, int y, int z)
{
return Item.getItemFromBlock(this);
}
/**
* Get the block's damage value (for use with pick block).
*/
public int getDamageValue(World worldIn, int x, int y, int z)
{
return this.damageDropped(worldIn.getBlockMetadata(x, y, z));
}
/**
* returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks)
*/
@SideOnly(Side.CLIENT)
public void getSubBlocks(Item itemIn, CreativeTabs tab, List list)
{
list.add(new ItemStack(itemIn, 1, 0));
}
public Block setCreativeTab(CreativeTabs tab)
{
this.displayOnCreativeTab = tab;
return this;
}
/**
* Called when the block is attempted to be harvested
*/
public void onBlockHarvested(World worldIn, int x, int y, int z, int meta, EntityPlayer player) {}
/**
* Returns the CreativeTab to display the given block on.
*/
@SideOnly(Side.CLIENT)
public CreativeTabs getCreativeTabToDisplayOn()
{
return this.displayOnCreativeTab;
}
public void onBlockPreDestroy(World worldIn, int x, int y, int z, int meta) {}
/**
* currently only used by BlockCauldron to incrament meta-data during rain
*/
public void fillWithRain(World worldIn, int x, int y, int z) {}
/**
* Returns true only if block is flowerPot
*/
@SideOnly(Side.CLIENT)
public boolean isFlowerPot()
{
return false;
}
public boolean requiresUpdates()
{
return true;
}
/**
* Return whether this block can drop from an explosion.
*/
public boolean canDropFromExplosion(Explosion explosionIn)
{
return true;
}
public boolean isAssociatedBlock(Block other)
{
return this == other;
}
public static boolean isEqualTo(Block blockIn, Block other)
{
return blockIn != null && other != null ? (blockIn == other ? true : blockIn.isAssociatedBlock(other)) : false;
}
public boolean hasComparatorInputOverride()
{
return false;
}
public int getComparatorInputOverride(World worldIn, int x, int y, int z, int side)
{
return 0;
}
public Block setTextureName(String textureName)
{
this.textureName = textureName;
return this;
}
@SideOnly(Side.CLIENT)
protected String getTextureName()
{
return this.textureName == null ? "MISSING_ICON_BLOCK_" + getIdFromBlock(this) + "_" + this.unlocalizedName : this.textureName;
}
@SideOnly(Side.CLIENT)
public IIcon getItemIcon(int side, int meta)
{
return this.getIcon(side, meta);
}
@SideOnly(Side.CLIENT)
public void registerIcons(IIconRegister reg)
{
this.blockIcon = reg.registerIcon(this.getTextureName());
}
/**
* Gets the icon name of the ItemBlock corresponding to this block. Used by hoppers.
*/
@SideOnly(Side.CLIENT)
public String getItemIconName()
{
return null;
}
/* ======================================== FORGE START =====================================*/
//For ForgeInternal use Only!
protected ThreadLocal<EntityPlayer> harvesters = new ThreadLocal();
private ThreadLocal<Integer> silk_check_meta = new ThreadLocal();
/**
* Get a light value for the block at the specified coordinates, normal ranges are between 0 and 15
*
* @param world The current world
* @param x X Position
* @param y Y position
* @param z Z position
* @return The light value
*/
public int getLightValue(IBlockAccess world, int x, int y, int z)
{
Block block = world.getBlock(x, y, z);
if (block != this)
{
return block.getLightValue(world, x, y, z);
}
return getLightValue();
}
/**
* Checks if a player or entity can use this block to 'climb' like a ladder.
*
* @param world The current world
* @param x X Position
* @param y Y position
* @param z Z position
* @param entity The entity trying to use the ladder, CAN be null.
* @return True if the block should act like a ladder
*/
public boolean isLadder(IBlockAccess world, int x, int y, int z, EntityLivingBase entity)
{
return false;
}
/**
* Return true if the block is a normal, solid cube. This
* determines indirect power state, entity ejection from blocks, and a few
* others.
*
* @param world The current world
* @param x X Position
* @param y Y position
* @param z Z position
* @return True if the block is a full cube
*/
public boolean isNormalCube(IBlockAccess world, int x, int y, int z)
{
/**
* Get a material of block
*/
return getMaterial().isOpaque() && renderAsNormalBlock() && !canProvidePower();
}
/**
* Checks if the block is a solid face on the given side, used by placement logic.
*
* @param world The current world
* @param x X Position
* @param y Y position
* @param z Z position
* @param side The side to check
* @return True if the block is solid on the specified side.
*/
public boolean isSideSolid(IBlockAccess world, int x, int y, int z, ForgeDirection side)
{
int meta = world.getBlockMetadata(x, y, z);
if (this instanceof BlockSlab)
{
return (((meta & 8) == 8 && (side == UP)) || isFullBlock());
}
else if (this instanceof BlockFarmland)
{
return (side != DOWN && side != UP);
}
else if (this instanceof BlockStairs)
{
boolean flipped = ((meta & 4) != 0);
return ((meta & 3) + side.ordinal() == 5) || (side == UP && flipped);
}
else if (this instanceof BlockSnow)
{
return (meta & 7) == 7;
}
else if (this instanceof BlockHopper && side == UP)
{
return true;
}
else if (this instanceof BlockCompressedPowered)
{
return true;
}
return isNormalCube(world, x, y, z);
}
/**
* Determines if a new block can be replace the space occupied by this one,
* Used in the player's placement code to make the block act like water, and lava.
*
* @param world The current world
* @param x X Position
* @param y Y position
* @param z Z position
* @return True if the block is replaceable by another block
*/
public boolean isReplaceable(IBlockAccess world, int x, int y, int z)
{
return blockMaterial.isReplaceable();
}
/**
* Determines if this block should set fire and deal fire damage
* to entities coming into contact with it.
*
* @param world The current world
* @param x X Position
* @param y Y position
* @param z Z position
* @return True if the block should deal damage
*/
public boolean isBurning(IBlockAccess world, int x, int y, int z)
{
return false;
}
/**
* Determines this block should be treated as an air block
* by the rest of the code. This method is primarily
* useful for creating pure logic-blocks that will be invisible
* to the player and otherwise interact as air would.
*
* @param world The current world
* @param x X Position
* @param y Y position
* @param z Z position
* @return True if the block considered air
*/
public boolean isAir(IBlockAccess world, int x, int y, int z)
{
/**
* Get a material of block
*/
return getMaterial() == Material.air;
}
/**
* Determines if the player can harvest this block, obtaining it's drops when the block is destroyed.
*
* @param player The player damaging the block, may be null
* @param meta The block's current metadata
* @return True to spawn the drops
*/
public boolean canHarvestBlock(EntityPlayer player, int meta)
{
return ForgeHooks.canHarvestBlock(this, player, meta);
}
/**
* Called when a player removes a block. This is responsible for
* actually destroying the block, and the block is intact at time of call.
* This is called regardless of whether the player can harvest the block or
* not.
*
* Return true if the block is actually destroyed.
*
* Note: When used in multiplayer, this is called on both client and
* server sides!
*
* @param world The current world
* @param player The player damaging the block, may be null
* @param x X Position
* @param y Y position
* @param z Z position
* @param willHarvest True if Block.harvestBlock will be called after this, if the return in true.
* Can be useful to delay the destruction of tile entities till after harvestBlock
* @return True if the block is actually destroyed.
*/
public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z, boolean willHarvest)
{
return removedByPlayer(world, player, x, y, z);
}
@Deprecated
public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z)
{
return world.setBlockToAir(x, y, z);
}
/**
* Chance that fire will spread and consume this block.
* 300 being a 100% chance, 0, being a 0% chance.
*
* @param world The current world
* @param x The blocks X position
* @param y The blocks Y position
* @param z The blocks Z position
* @param face The face that the fire is coming from
* @return A number ranging from 0 to 300 relating used to determine if the block will be consumed by fire
*/
public int getFlammability(IBlockAccess world, int x, int y, int z, ForgeDirection face)
{
return Blocks.fire.getFlammability(this);
}
/**
* Called when fire is updating, checks if a block face can catch fire.
*
*
* @param world The current world
* @param x The blocks X position
* @param y The blocks Y position
* @param z The blocks Z position
* @param face The face that the fire is coming from
* @return True if the face can be on fire, false otherwise.
*/
public boolean isFlammable(IBlockAccess world, int x, int y, int z, ForgeDirection face)
{
return getFlammability(world, x, y, z, face) > 0;
}
/**
* Called when fire is updating on a neighbor block.
* The higher the number returned, the faster fire will spread around this block.
*
* @param world The current world
* @param x The blocks X position
* @param y The blocks Y position
* @param z The blocks Z position
* @param face The face that the fire is coming from
* @return A number that is used to determine the speed of fire growth around the block
*/
public int getFireSpreadSpeed(IBlockAccess world, int x, int y, int z, ForgeDirection face)
{
return Blocks.fire.getEncouragement(this);
}
/**
* Currently only called by fire when it is on top of this block.
* Returning true will prevent the fire from naturally dying during updating.
* Also prevents firing from dying from rain.
*
* @param world The current world
* @param x The blocks X position
* @param y The blocks Y position
* @param z The blocks Z position
* @param metadata The blocks current metadata
* @param side The face that the fire is coming from
* @return True if this block sustains fire, meaning it will never go out.
*/
public boolean isFireSource(World world, int x, int y, int z, ForgeDirection side)
{
if (this == Blocks.netherrack && side == UP)
{
return true;
}
if ((world.provider instanceof WorldProviderEnd) && this == Blocks.bedrock && side == UP)
{
return true;
}
return false;
}
private boolean isTileProvider = this instanceof ITileEntityProvider;
/**
* Called throughout the code as a replacement for block instanceof BlockContainer
* Moving this to the Block base class allows for mods that wish to extend vanilla
* blocks, and also want to have a tile entity on that block, may.
*
* Return true from this function to specify this block has a tile entity.
*
* @param metadata Metadata of the current block
* @return True if block has a tile entity, false otherwise
*/
public boolean hasTileEntity(int metadata)
{
return isTileProvider;
}
/**
* Called throughout the code as a replacement for ITileEntityProvider.createNewTileEntity
* Return the same thing you would from that function.
* This will fall back to ITileEntityProvider.createNewTileEntity(World) if this block is a ITileEntityProvider
*
* @param metadata The Metadata of the current block
* @return A instance of a class extending TileEntity
*/
public TileEntity createTileEntity(World world, int metadata)
{
if (isTileProvider)
{
return ((ITileEntityProvider)this).createNewTileEntity(world, metadata);
}
return null;
}
/**
* Metadata and fortune sensitive version, this replaces the old (int meta, Random rand)
* version in 1.1.
*
* @param meta Blocks Metadata
* @param fortune Current item fortune level
* @param random Random number generator
* @return The number of items to drop
*/
public int quantityDropped(int meta, int fortune, Random random)
{
/**
* Returns the usual quantity dropped by the block plus a bonus of 1 to 'i' (inclusive).
*/
return quantityDroppedWithBonus(fortune, random);
}
/**
* This returns a complete list of items dropped from this block.
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z Position
* @param metadata Current metadata
* @param fortune Breakers fortune level
* @return A ArrayList containing all items this block drops
*/
public ArrayList<ItemStack> getDrops(World world, int x, int y, int z, int metadata, int fortune)
{
ArrayList<ItemStack> ret = new ArrayList<ItemStack>();
int count = quantityDropped(metadata, fortune, world.rand);
for(int i = 0; i < count; i++)
{
Item item = getItemDropped(metadata, world.rand, fortune);
if (item != null)
{
ret.add(new ItemStack(item, 1, damageDropped(metadata)));
}
}
return ret;
}
/**
* Return true from this function if the player with silk touch can harvest this block directly, and not it's normal drops.
*
* @param world The world
* @param player The player doing the harvesting
* @param x X Position
* @param y Y Position
* @param z Z Position
* @param metadata The metadata
* @return True if the block can be directly harvested using silk touch
*/
public boolean canSilkHarvest(World world, EntityPlayer player, int x, int y, int z, int metadata)
{
silk_check_meta.set(metadata);;
boolean ret = this.canSilkHarvest();
silk_check_meta.set(null);
return ret;
}
/**
* Determines if a specified mob type can spawn on this block, returning false will
* prevent any mob from spawning on the block.
*
* @param type The Mob Category Type
* @param world The current world
* @param x The X Position
* @param y The Y Position
* @param z The Z Position
* @return True to allow a mob of the specified category to spawn, false to prevent it.
*/
public boolean canCreatureSpawn(EnumCreatureType type, IBlockAccess world, int x, int y, int z)
{
int meta = world.getBlockMetadata(x, y, z);
if (this instanceof BlockSlab)
{
return (((meta & 8) == 8) || isFullBlock());
}
else if (this instanceof BlockStairs)
{
return ((meta & 4) != 0);
}
return isSideSolid(world, x, y, z, UP);
}
/**
* Determines if this block is classified as a Bed, Allowing
* players to sleep in it, though the block has to specifically
* perform the sleeping functionality in it's activated event.
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z Position
* @param player The player or camera entity, null in some cases.
* @return True to treat this as a bed
*/
public boolean isBed(IBlockAccess world, int x, int y, int z, EntityLivingBase player)
{
return this == Blocks.bed;
}
/**
* Returns the position that the player is moved to upon
* waking up, or respawning at the bed.
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z Position
* @param player The player or camera entity, null in some cases.
* @return The spawn position
*/
public ChunkCoordinates getBedSpawnPosition(IBlockAccess world, int x, int y, int z, EntityPlayer player)
{
if (world instanceof World)
return BlockBed.getSafeExitLocation((World)world, x, y, z, 0);
return null;
}
/**
* Called when a user either starts or stops sleeping in the bed.
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z Position
* @param player The player or camera entity, null in some cases.
* @param occupied True if we are occupying the bed, or false if they are stopping use of the bed
*/
public void setBedOccupied(IBlockAccess world, int x, int y, int z, EntityPlayer player, boolean occupied)
{
if (world instanceof World)
BlockBed.setBedOccupied((World)world, x, y, z, occupied);
}
/**
* Returns the direction of the block. Same values that
* are returned by BlockDirectional
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z Position
* @return Bed direction
*/
public int getBedDirection(IBlockAccess world, int x, int y, int z)
{
return BlockBed.getDirection(world.getBlockMetadata(x, y, z));
}
/**
* Determines if the current block is the foot half of the bed.
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z Position
* @return True if the current block is the foot side of a bed.
*/
public boolean isBedFoot(IBlockAccess world, int x, int y, int z)
{
return BlockBed.isBlockHeadOfBed(world.getBlockMetadata(x, y, z));
}
/**
* Called when a leaf should start its decay process.
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z Position
*/
public void beginLeavesDecay(World world, int x, int y, int z){}
/**
* Determines if this block can prevent leaves connected to it from decaying.
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z Position
* @return true if the presence this block can prevent leaves from decaying.
*/
public boolean canSustainLeaves(IBlockAccess world, int x, int y, int z)
{
return false;
}
/**
* Determines if this block is considered a leaf block, used to apply the leaf decay and generation system.
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z Position
* @return true if this block is considered leaves.
*/
public boolean isLeaves(IBlockAccess world, int x, int y, int z)
{
/**
* Get a material of block
*/
return getMaterial() == Material.leaves;
}
/**
* Used during tree growth to determine if newly generated leaves can replace this block.
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z Position
* @return true if this block can be replaced by growing leaves.
*/
public boolean canBeReplacedByLeaves(IBlockAccess world, int x, int y, int z)
{
return !isFullBlock();
}
/**
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z Position
* @return true if the block is wood (logs)
*/
public boolean isWood(IBlockAccess world, int x, int y, int z)
{
return false;
}
/**
* Determines if the current block is replaceable by Ore veins during world generation.
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z Position
* @param target The generic target block the gen is looking for, Standards define stone
* for overworld generation, and neatherack for the nether.
* @return True to allow this block to be replaced by a ore
*/
public boolean isReplaceableOreGen(World world, int x, int y, int z, Block target)
{
return this == target;
}
/**
* Location sensitive version of getExplosionRestance
*
* @param par1Entity The entity that caused the explosion
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z Position
* @param explosionX Explosion source X Position
* @param explosionY Explosion source X Position
* @param explosionZ Explosion source X Position
* @return The amount of the explosion absorbed.
*/
public float getExplosionResistance(Entity par1Entity, World world, int x, int y, int z, double explosionX, double explosionY, double explosionZ)
{
/**
* Returns how much this block can resist explosions from the passed in entity.
*/
return getExplosionResistance(par1Entity);
}
/**
* Called when the block is destroyed by an explosion.
* Useful for allowing the block to take into account tile entities,
* metadata, etc. when exploded, before it is removed.
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z Position
* @param Explosion The explosion instance affecting the block
*/
public void onBlockExploded(World world, int x, int y, int z, Explosion explosion)
{
world.setBlockToAir(x, y, z);
onBlockDestroyedByExplosion(world, x, y, z, explosion);
}
/**
* Determine if this block can make a redstone connection on the side provided,
* Useful to control which sides are inputs and outputs for redstone wires.
*
* Side:
* -1: UP
* 0: NORTH
* 1: EAST
* 2: SOUTH
* 3: WEST
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z Position
* @param side The side that is trying to make the connection
* @return True to make the connection
*/
public boolean canConnectRedstone(IBlockAccess world, int x, int y, int z, int side)
{
/**
* Can this block provide power. Only wire currently seems to have this change based on its state.
*/
return canProvidePower() && side != -1;
}
/**
* Determines if a torch can be placed on the top surface of this block.
* Useful for creating your own block that torches can be on, such as fences.
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z Position
* @return True to allow the torch to be placed
*/
public boolean canPlaceTorchOnTop(World world, int x, int y, int z)
{
if (isSideSolid(world, x, y, z, UP))
{
return true;
}
else
{
return this == Blocks.fence || this == Blocks.nether_brick_fence || this == Blocks.glass || this == Blocks.cobblestone_wall;
}
}
/**
* Determines if this block should render in this pass.
*
* @param pass The pass in question
* @return True to render
*/
public boolean canRenderInPass(int pass)
{
return pass == getRenderBlockPass();
}
/**
* Called when a user uses the creative pick block button on this block
*
* @param target The full target the player is looking at
* @return A ItemStack to add to the player's inventory, Null if nothing should be added.
*/
public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z, EntityPlayer player)
{
return getPickBlock(target, world, x, y, z);
}
@Deprecated
public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z)
{
Item item = getItem(world, x, y, z);
if (item == null)
{
return null;
}
Block block = item instanceof ItemBlock && !isFlowerPot() ? Block.getBlockFromItem(item) : this;
return new ItemStack(item, 1, block.getDamageValue(world, x, y, z));
}
/**
* Used by getTopSolidOrLiquidBlock while placing biome decorations, villages, etc
* Also used to determine if the player can spawn on this block.
*
* @return False to disallow spawning
*/
public boolean isFoliage(IBlockAccess world, int x, int y, int z)
{
return false;
}
/**
* Spawn a digging particle effect in the world, this is a wrapper
* around EffectRenderer.addBlockHitEffects to allow the block more
* control over the particles. Useful when you have entirely different
* texture sheets for different sides/locations in the world.
*
* @param world The current world
* @param target The target the player is looking at {x/y/z/side/sub}
* @param effectRenderer A reference to the current effect renderer.
* @return True to prevent vanilla digging particles form spawning.
*/
@SideOnly(Side.CLIENT)
public boolean addHitEffects(World worldObj, MovingObjectPosition target, EffectRenderer effectRenderer)
{
return false;
}
/**
* Spawn particles for when the block is destroyed. Due to the nature
* of how this is invoked, the x/y/z locations are not always guaranteed
* to host your block. So be sure to do proper sanity checks before assuming
* that the location is this block.
*
* @param world The current world
* @param x X position to spawn the particle
* @param y Y position to spawn the particle
* @param z Z position to spawn the particle
* @param meta The metadata for the block before it was destroyed.
* @param effectRenderer A reference to the current effect renderer.
* @return True to prevent vanilla break particles from spawning.
*/
@SideOnly(Side.CLIENT)
public boolean addDestroyEffects(World world, int x, int y, int z, int meta, EffectRenderer effectRenderer)
{
return false;
}
/**
* Determines if this block can support the passed in plant, allowing it to be planted and grow.
* Some examples:
* Reeds check if its a reed, or if its sand/dirt/grass and adjacent to water
* Cacti checks if its a cacti, or if its sand
* Nether types check for soul sand
* Crops check for tilled soil
* Caves check if it's a solid surface
* Plains check if its grass or dirt
* Water check if its still water
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z position
* @param direction The direction relative to the given position the plant wants to be, typically its UP
* @param plantable The plant that wants to check
* @return True to allow the plant to be planted/stay.
*/
public boolean canSustainPlant(IBlockAccess world, int x, int y, int z, ForgeDirection direction, IPlantable plantable)
{
Block plant = plantable.getPlant(world, x, y + 1, z);
EnumPlantType plantType = plantable.getPlantType(world, x, y + 1, z);
if (plant == Blocks.cactus && this == Blocks.cactus)
{
return true;
}
if (plant == Blocks.reeds && this == Blocks.reeds)
{
return true;
}
if (plantable instanceof BlockBush && ((BlockBush)plantable).canPlaceBlockOn(this))
{
return true;
}
switch (plantType)
{
case Desert: return this == Blocks.sand;
case Nether: return this == Blocks.soul_sand;
case Crop: return this == Blocks.farmland;
case Cave: return isSideSolid(world, x, y, z, UP);
case Plains: return this == Blocks.grass || this == Blocks.dirt || this == Blocks.farmland;
case Water: return world.getBlock(x, y, z).getMaterial() == Material.water && world.getBlockMetadata(x, y, z) == 0;
case Beach:
boolean isBeach = this == Blocks.grass || this == Blocks.dirt || this == Blocks.sand;
boolean hasWater = (world.getBlock(x - 1, y, z ).getMaterial() == Material.water ||
world.getBlock(x + 1, y, z ).getMaterial() == Material.water ||
world.getBlock(x, y, z - 1).getMaterial() == Material.water ||
world.getBlock(x, y, z + 1).getMaterial() == Material.water);
return isBeach && hasWater;
}
return false;
}
/**
* Called when a plant grows on this block, only implemented for saplings using the WorldGen*Trees classes right now.
* Modder may implement this for custom plants.
* This does not use ForgeDirection, because large/huge trees can be located in non-representable direction,
* so the source location is specified.
* Currently this just changes the block to dirt if it was grass.
*
* Note: This happens DURING the generation, the generation may not be complete when this is called.
*
* @param world Current world
* @param x Soil X
* @param y Soil Y
* @param z Soil Z
* @param sourceX Plant growth location X
* @param sourceY Plant growth location Y
* @param sourceZ Plant growth location Z
*/
public void onPlantGrow(World world, int x, int y, int z, int sourceX, int sourceY, int sourceZ)
{
if (this == Blocks.grass || this == Blocks.farmland)
{
world.setBlock(x, y, z, Blocks.dirt, 0, 2);
}
}
/**
* Checks if this soil is fertile, typically this means that growth rates
* of plants on this soil will be slightly sped up.
* Only vanilla case is tilledField when it is within range of water.
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z position
* @return True if the soil should be considered fertile.
*/
public boolean isFertile(World world, int x, int y, int z)
{
if (this == Blocks.farmland)
{
return world.getBlockMetadata(x, y, z) > 0;
}
return false;
}
/**
* Location aware and overrideable version of the lightOpacity array,
* return the number to subtract from the light value when it passes through this block.
*
* This is not guaranteed to have the tile entity in place before this is called, so it is
* Recommended that you have your tile entity call relight after being placed if you
* rely on it for light info.
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z position
* @return The amount of light to block, 0 for air, 255 for fully opaque.
*/
public int getLightOpacity(IBlockAccess world, int x, int y, int z)
{
return getLightOpacity();
}
/**
* Determines if this block is can be destroyed by the specified entities normal behavior.
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z position
* @return True to allow the ender dragon to destroy this block
*/
public boolean canEntityDestroy(IBlockAccess world, int x, int y, int z, Entity entity)
{
if (entity instanceof EntityWither)
{
return this != Blocks.bedrock && this != Blocks.end_portal && this != Blocks.end_portal_frame && this != Blocks.command_block;
}
else if (entity instanceof EntityDragon)
{
return this != Blocks.obsidian && this != Blocks.end_stone && this != Blocks.bedrock;
}
return true;
}
/**
* Determines if this block can be used as the base of a beacon.
*
* @param world The current world
* @param x X Position
* @param y Y Position
* @param z Z position
* @param beaconX Beacons X Position
* @param beaconY Beacons Y Position
* @param beaconZ Beacons Z Position
* @return True, to support the beacon, and make it active with this block.
*/
public boolean isBeaconBase(IBlockAccess worldObj, int x, int y, int z, int beaconX, int beaconY, int beaconZ)
{
return this == Blocks.emerald_block || this == Blocks.gold_block || this == Blocks.diamond_block || this == Blocks.iron_block;
}
/**
* Rotate the block. For vanilla blocks this rotates around the axis passed in (generally, it should be the "face" that was hit).
* Note: for mod blocks, this is up to the block and modder to decide. It is not mandated that it be a rotation around the
* face, but could be a rotation to orient *to* that face, or a visiting of possible rotations.
* The method should return true if the rotation was successful though.
*
* @param worldObj The world
* @param x X position
* @param y Y position
* @param z Z position
* @param axis The axis to rotate around
* @return True if the rotation was successful, False if the rotation failed, or is not possible
*/
public boolean rotateBlock(World worldObj, int x, int y, int z, ForgeDirection axis)
{
return RotationHelper.rotateVanillaBlock(this, worldObj, x, y, z, axis);
}
/**
* Get the rotations that can apply to the block at the specified coordinates. Null means no rotations are possible.
* Note, this is up to the block to decide. It may not be accurate or representative.
* @param worldObj The world
* @param x X position
* @param y Y position
* @param z Z position
* @return An array of valid axes to rotate around, or null for none or unknown
*/
public ForgeDirection[] getValidRotations(World worldObj, int x, int y, int z)
{
return RotationHelper.getValidVanillaBlockRotations(this);
}
/**
* Determines the amount of enchanting power this block can provide to an enchanting table.
* @param world The World
* @param x X position
* @param y Y position
* @param z Z position
* @return The amount of enchanting power this block produces.
*/
public float getEnchantPowerBonus(World world, int x, int y, int z)
{
return this == Blocks.bookshelf ? 1 : 0;
}
/**
* Common way to recolour a block with an external tool
* @param world The world
* @param x X
* @param y Y
* @param z Z
* @param side The side hit with the colouring tool
* @param colour The colour to change to
* @return If the recolouring was successful
*/
public boolean recolourBlock(World world, int x, int y, int z, ForgeDirection side, int colour)
{
if (this == Blocks.wool)
{
int meta = world.getBlockMetadata(x, y, z);
if (meta != colour)
{
world.setBlockMetadataWithNotify(x, y, z, colour, 3);
return true;
}
}
return false;
}
/**
* Gathers how much experience this block drops when broken.
*
* @param world The world
* @param metadata
* @param fortune
* @return Amount of XP from breaking this block.
*/
public int getExpDrop(IBlockAccess world, int metadata, int fortune)
{
return 0;
}
/**
* Called when a tile entity on a side of this block changes is created or is destroyed.
* @param world The world
* @param x The x position of this block instance
* @param y The y position of this block instance
* @param z The z position of this block instance
* @param tileX The x position of the tile that changed
* @param tileY The y position of the tile that changed
* @param tileZ The z position of the tile that changed
*/
public void onNeighborChange(IBlockAccess world, int x, int y, int z, int tileX, int tileY, int tileZ)
{
}
/**
* Called to determine whether to allow the a block to handle its own indirect power rather than using the default rules.
* @param world The world
* @param x The x position of this block instance
* @param y The y position of this block instance
* @param z The z position of this block instance
* @param side The INPUT side of the block to be powered - ie the opposite of this block's output side
* @return Whether Block#isProvidingWeakPower should be called when determining indirect power
*/
public boolean shouldCheckWeakPower(IBlockAccess world, int x, int y, int z, int side)
{
return isNormalCube();
}
/**
* If this block should be notified of weak changes.
* Weak changes are changes 1 block away through a solid block.
* Similar to comparators.
*
* @param world The current world
* @param x X Position
* @param y Y position
* @param z Z position
* @param side The side to check
* @return true To be notified of changes
*/
public boolean getWeakChanges(IBlockAccess world, int x, int y, int z)
{
return false;
}
private String[] harvestTool = new String[16];
private int[] harvestLevel = new int[]{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
/**
* Sets or removes the tool and level required to harvest this block.
*
* @param toolClass Class
* @param level Harvest level:
* Wood: 0
* Stone: 1
* Iron: 2
* Diamond: 3
* Gold: 0
*/
public void setHarvestLevel(String toolClass, int level)
{
for (int m = 0; m < 16; m++)
{
setHarvestLevel(toolClass, level, m);
}
}
/**
* Sets or removes the tool and level required to harvest this block.
*
* @param toolClass Class
* @param level Harvest level:
* Wood: 0
* Stone: 1
* Iron: 2
* Diamond: 3
* Gold: 0
* @param metadata The specific metadata to set
*/
public void setHarvestLevel(String toolClass, int level, int metadata)
{
this.harvestTool[metadata] = toolClass;
this.harvestLevel[metadata] = level;
}
/**
* Queries the class of tool required to harvest this block, if null is returned
* we assume that anything can harvest this block.
*
* @param metadata
* @return
*/
public String getHarvestTool(int metadata)
{
return harvestTool[metadata];
}
/**
* Queries the harvest level of this item stack for the specifred tool class,
* Returns -1 if this tool is not of the specified type
*
* @param stack This item stack instance
* @return Harvest level, or -1 if not the specified tool type.
*/
public int getHarvestLevel(int metadata)
{
return harvestLevel[metadata];
}
/**
* Checks if the specified tool type is efficient on this block,
* meaning that it digs at full speed.
*
* @param type
* @param metadata
* @return
*/
public boolean isToolEffective(String type, int metadata)
{
if ("pickaxe".equals(type) && (this == Blocks.redstone_ore || this == Blocks.lit_redstone_ore || this == Blocks.obsidian))
return false;
if (harvestTool[metadata] == null) return false;
return harvestTool[metadata].equals(type);
}
// For Inernal use only to capture droped items inside getDrops
protected ThreadLocal<Boolean> captureDrops = new ThreadLocal<Boolean>()
{
@Override protected Boolean initialValue() { return false; }
};
protected ThreadLocal<List<ItemStack>> capturedDrops = new ThreadLocal<List<ItemStack>>()
{
@Override protected List<ItemStack> initialValue() { return new ArrayList<ItemStack>(); }
};
protected List<ItemStack> captureDrops(boolean start)
{
if (start)
{
captureDrops.set(true);
capturedDrops.get().clear();
return null;
}
else
{
captureDrops.set(false);
return capturedDrops.get();
}
}
/* ========================================= FORGE END ======================================*/
public static class SoundType
{
public final String soundName;
public final float volume;
public final float frequency;
private static final String __OBFID = "CL_00000203";
public SoundType(String name, float volume, float frequency)
{
this.soundName = name;
this.volume = volume;
this.frequency = frequency;
}
public float getVolume()
{
return this.volume;
}
public float getFrequency()
{
return this.frequency;
}
public String getDigResourcePath()
{
return "dig." + this.soundName;
}
public String getStepSound()
{
return "step." + this.soundName;
}
public String getPlaceSound()
{
return this.getDigResourcePath();
}
}
}