public class BlockSoil extends Block {

    public BlockSoil() {
        super(Material.clay);
        setBlockName("soilBlock");
        setHardness(2.0f);
        setCreativeTab(AntiMatterModRegistry.tabMaterials);
        setBlockTextureName(AntiMatterModCore.MOD_ID + ":blocks/soilBlock");
        setHarvestLevel("shovel", 1);
        setStepSound(soundTypeGravel);
    }

    @Override
    public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z, boolean willHarvest) {
        //手持ちのアイテムを取得する、nullの場合はelseのほうに飛ぶ
        if (player.getHeldItem() != null && player.getHeldItem().getItem() == Items.stone_shovel){
            //ブロック配置
            world.setBlock(x,y,z,AntiMatterModRegistry.satStove);
            //粘土ドロップ
            player.dropItem(Items.clay_ball,1);
            return false;
        }else{
            //いつもの破壊
            return super.removedByPlayer(world,player,x,y,z,willHarvest);
        }
    }

} public class ClayCrucible extends BlockContainer {
	
	public IIcon meltedIron;
	
	public ClayCrucible() {
		super(Material.rock);
		this.setBlockName("claycrucible");
		this.setCreativeTab(AntiMatterModRegistry.tabMachines);
		this.setResistance(5F);
		this.setHardness(10F);
		this.setHarvestLevel("pickaxe", 1);
	}
	
	
	@Override
	public TileEntity createNewTileEntity(World world, int meta) {
		return new TileEntityClayCrucible();
	}
	
	@Override
	public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) {
		//手持ちアイテムの判定
		ItemStack heldItem;
		
		
		if (world.getTileEntity(x, y, z) instanceof TileEntityClayCrucible) {
			
			//タイルエンチチーのしゅとく
			TileEntityClayCrucible tile = (TileEntityClayCrucible) world.getTileEntity(x, y, z);
			
			//手持ち無しの場合か、粘土るつぼパターンの場合
			if ((heldItem = player.getHeldItem()) == null || heldItem.getItem() instanceof ClayCruciblePattern) {
				player.inventory.mainInventory[player.inventory.currentItem] = tile.setMode(heldItem);
				return true;
			}
			
			//その他だった場合
			int addSize = tile.addOres(player.getHeldItem());
			if (addSize != 0) {
				heldItem.stackSize -= addSize;
				tile.markDirty();
				player.inventory.markDirty();
				world.markBlockForUpdate(x, y, z);
			}
			return addSize > 0;
		} else {
			return false;
		}
	}
	
	
	@Override
	public void breakBlock(World world, int x, int y, int z, Block block, int meta) {
		TileEntity tileEntity = world.getTileEntity(x, y, z);
		if (tileEntity instanceof TileEntityClayCrucible) {
			TileEntityClayCrucible entity = (TileEntityClayCrucible) tileEntity;
			switch (entity.getState()) {
				case NONE:
				case HEATING:
					if (entity.getStack() != null) this.dropBlockAsItem(world, x, y, z, entity.getStack());
					ItemStack stack;
					if ((stack = entity.setMode(null)) != null) {
						this.dropBlockAsItem(world, x, y, z, stack);
					}
					break;
				
				case MELTED:
					break;
				case SOLIDIFIED:
					this.dropBlockAsItem(world, x, y, z, entity.getDropCompletionItem());
					break;
			}
			
		}
		
		super.breakBlock(world, x, y, z, block, meta);
	}
	
	
	@Override
	public void onBlockHarvested(World world, int x, int y, int z, int meta, EntityPlayer player) {
		TileEntity tileEntity = world.getTileEntity(x, y, z);
		if (tileEntity instanceof TileEntityClayCrucible) {
			TileEntityClayCrucible entity = (TileEntityClayCrucible) tileEntity;
			switch (entity.getState()) {
				case MELTED:
					player.attackEntityFrom(DamageSource.magic, 10F);
					break;
			}
		}
	}
	
	
	@Override
	public boolean canHarvestBlock(EntityPlayer player, int meta) {
		return meta == 0 && super.canHarvestBlock(player, meta);
	}
	
	@Override
	protected boolean canSilkHarvest() {
		return false;
	}
	
	@Override
	public boolean isReplaceableOreGen(World world, int x, int y, int z, Block target) {
		return true;
	}
	
	@Override
	public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z, boolean willHarvest) {
		return super.removedByPlayer(world, player, x, y, z, willHarvest);
		
	}
	
	@Override
	public int getRenderType() {
		return -1;
	}
	
	@Override
	public void addCollisionBoxesToList(World world, int x, int y, int z, AxisAlignedBB aabb, List list, Entity entity) {
		this.setBlockBounds(2F / 16F, 0F, 2F / 16F, 14F / 16F, 14F / 16, 14F / 16F);
		super.addCollisionBoxesToList(world, x, y, z, aabb, list, entity);
	}
	
	@Override
	public void registerBlockIcons(IIconRegister register) {
		this.blockIcon = Blocks.hardened_clay.getIcon(0, 0);
		this.meltedIron = register.registerIcon(AntiMatterModCore.MOD_ID + ":liquid/liquid_iron");
	}
	
	@Override
	public boolean isNormalCube() {
		return false;
	}
	
	@Override
	public boolean isOpaqueCube() {
		return false;
	}
	
	@Override
	public boolean renderAsNormalBlock() {
		return false;
	}
	
} public class ClayCrucibleHeater extends BlockContainer {
	
	
	private IIcon iIcon_TOP;
	
	//コンストラクタ
	public ClayCrucibleHeater() {
		super(Material.rock);
		this.setBlockName("claycrucibleheater");
		this.setBlockTextureName(AntiMatterModCore.MOD_ID + ":another/claycrucibleheater");
		this.setCreativeTab(AntiMatterModRegistry.tabMachines);
		this.setResistance(5F);
		this.setHardness(10F);
		this.setHarvestLevel("pickaxe", 1);
	}
	
	//TileEntityの取得
	@Override
	public TileEntity createNewTileEntity(World world, int meta) {
		return new TileEntityClayCrucibleHeater();
	}
	
	@Override
	public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float pX, float pY, float pZ) {
		
		TileEntity tileEntity = world.getTileEntity(x, y, z);
		if (tileEntity instanceof TileEntityClayCrucibleHeater) {
			ItemStack stack = player.getHeldItem();
			TileEntityClayCrucibleHeater tile = (TileEntityClayCrucibleHeater) tileEntity;
			
			if (stack == null) {
				stack = tile.removeFuel();
				player.inventory.mainInventory[player.inventory.currentItem] = stack;
				return true;
			} else if (stack.getItem() == Items.coal) {
				tile.addFuel(stack);
				return true;
			}
		}
		return false;
	}
	
	@Override
	public void dropBlockAsItem(World world, int x, int y, int z, ItemStack stack) {
		super.dropBlockAsItem(world, x, y, z, stack);
	}
	
	//ブロック破壊時のアイテムドロップ
	@Override
	public void breakBlock(World world, int x, int y, int z, Block block, int meta) {
		TileEntity entity;
		if ((entity = world.getTileEntity(x, y, z)) instanceof TileEntityClayCrucibleHeater)
			((TileEntityClayCrucibleHeater) entity).dropItems(this, world, x, y, z);
		super.breakBlock(world, x, y, z, block, meta);
	}
	
	//テクスチャ―のリソース生成
	@Override
	public void registerBlockIcons(IIconRegister register) {
		this.iIcon_TOP = register.registerIcon(this.getTextureName());
	}
	
	//テクスチャ―の取得
	@Override
	@SideOnly(Side.CLIENT)
	public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		int meta = world.getBlockMetadata(x, y, z);
		if (side == 1) return this.iIcon_TOP;
		if (side == 0) return Blocks.furnace.getIcon(0, 0);
		return side == meta ? Blocks.furnace.getIcon(2, 2) : side == meta - 6 ? Blocks.lit_furnace.getIcon(2, 2) : Blocks.furnace.getIcon(2, 3);
	}
	
	//テクスチャ―の取得
	@Override
	@SideOnly(Side.CLIENT)
	public IIcon getIcon(int side, int meta) {
		switch (side) {
			case 0:
				return Blocks.furnace.getIcon(0, 0);
			case 1:
				return this.iIcon_TOP;
			case 3:
				return Blocks.furnace.getIcon(2, 2);
			default:
				return Blocks.furnace.getIcon(2, 3);
		}
	}
	
	//ブロックが設置されたとき
	@Override
	public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase entityLivingBase, ItemStack itemStack) {
		
		int playerDir = MathHelper.floor_double((double) (entityLivingBase.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
		ForgeDirection[] blockDir = {ForgeDirection.NORTH, ForgeDirection.EAST, ForgeDirection.SOUTH, ForgeDirection.WEST};
		world.setBlockMetadataWithNotify(x, y, z, blockDir[playerDir].ordinal(), 2);
	}
	
	@Override
	public int getLightValue(IBlockAccess world, int x, int y, int z) {
		return world.getBlockMetadata(x, y, z) < 6 ? 0 : 15;
	}

} public class TileEntityClayCrucible extends TileEntity {
	
	private ItemStack stack;
	
	private ClayCruciblePattern.ClayCruciblePatternList modeMeta = null;
	
	private int MaxOres = 9;
	
	private int time;
	
	private ClayCrucibleState state = ClayCrucibleState.NONE;
	
	
	public TileEntityClayCrucible() {
		
	}
	
	@Override
	public void writeToNBT(NBTTagCompound nbtTag) {
		super.writeToNBT(nbtTag);
		NBTTagCompound compound = new NBTTagCompound();
		if (this.stack != null) this.stack.writeToNBT(compound);
		nbtTag.setTag("Item", compound);
		nbtTag.setInteger("time", this.time);
		nbtTag.setByte("mode", (byte) (this.modeMeta == null ? -1 : this.modeMeta.ordinal()));
		nbtTag.setByte("state", (byte) this.state.ordinal());
	}
	
	@Override
	public void readFromNBT(NBTTagCompound nbtTag) {
		super.readFromNBT(nbtTag);
		NBTTagCompound compound = nbtTag.getCompoundTag("Item");
		this.stack = ItemStack.loadItemStackFromNBT(compound);
		this.time = nbtTag.getInteger("time");
		byte modeB = nbtTag.getByte("mode");
		this.modeMeta = modeB == -1 ? null : ClayCruciblePattern.ClayCruciblePatternList.values()[modeB];
		this.MaxOres = this.modeMeta == null ? 9 : this.modeMeta.stackSize;
		this.state = ClayCrucibleState.values()[nbtTag.getByte("state")];
	}
	
	@Override
	public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) {
		readFromNBT(pkt.func_148857_g());
	}
	
	@Override
	public Packet getDescriptionPacket() {
		NBTTagCompound tagCompound = new NBTTagCompound();
		writeToNBT(tagCompound);
		return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, 1, tagCompound);
	}
	
	@Override
	public void updateEntity() {
		if (!this.worldObj.isRemote) {
			switch (this.state) {
				case NONE://何もしていない状態
					heatingCheck();
					this.time = this.time <= 0 ? 0 : this.time - 1;
					break;
				case HEATING://加熱中処理
					if (this.time > 200 * this.stack.stackSize) {
						this.state = ClayCrucibleState.MELTED;
						this.worldObj.setBlockMetadataWithNotify(this.xCoord, this.yCoord, this.zCoord, 1, 0);
						this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord);
					} else {
						heatingCheck();
						this.time++;
					}
					break;
				case MELTED://溶けた後の処理
					if (this.time <= 0) {
						this.state = ClayCrucibleState.SOLIDIFIED;
						this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord);
					} else {
						coolingCheck();
						this.time--;
					}
					break;
				case SOLIDIFIED://固めた後の処理
					break;
			}
		}
	}
	
	public ItemStack getDropCompletionItem() {
		return new ItemStack(this.modeMeta.completionItem, 1, this.modeMeta.itemMeta);
	}
	
	private void heatingCheck() {
		if (this.stack == null || this.stack.stackSize != this.MaxOres) {
			this.state = ClayCrucibleState.NONE;
			return;
		}
		TileEntity tileEntity = this.worldObj.getTileEntity(this.xCoord, this.yCoord - 1, this.zCoord);
		if (tileEntity instanceof TileEntityClayCrucibleHeater) {
			if (((TileEntityClayCrucibleHeater) tileEntity).isBurning()) {
				this.state = ClayCrucibleState.HEATING;
			} else {
				this.state = ClayCrucibleState.NONE;
			}
		}
		
	}
	
	private void coolingCheck() {
		TileEntity tileEntity = this.worldObj.getTileEntity(this.xCoord, this.yCoord - 1, this.zCoord);
		if (tileEntity instanceof TileEntityClayCrucibleHeater) {
			if (((TileEntityClayCrucibleHeater) tileEntity).isBurning()) {
				this.time++;
			}
		}
		
	}
	
	public int addOres(ItemStack stack) {
		if (stack.getItem() == Items.iron_ingot) {
			if (this.stack == null) {
				ItemStack addStack = stack.copy();
				addStack.stackSize = addStack.stackSize <= this.MaxOres ? addStack.stackSize : this.MaxOres;
				this.stack = addStack;
				return addStack.stackSize;
			} else if (this.stack.stackSize < this.MaxOres && stack.getItem() == this.getStack().getItem()) {
				int a = this.MaxOres - this.stack.stackSize;
				ItemStack addStack = stack.copy();
				addStack.stackSize = addStack.stackSize <= a ? addStack.stackSize : a;
				this.getStack().stackSize += addStack.stackSize;
				return addStack.stackSize;
			}
		}
		return 0;
	}
	
	public ItemStack setMode(ItemStack stack) {
		this.time = 0;//タイマーを初期化
		this.state = ClayCrucibleState.NONE;
		if (stack != null && stack.getItem() instanceof ClayCruciblePattern) {
			ItemStack retItemStack = this.modeMeta == null ? null : new ItemStack(AntiMatterModRegistry.clayCruciblePattern, 1, this.modeMeta.ordinal());
			this.modeMeta = ClayCruciblePattern.ClayCruciblePatternList.values()[stack.getItemDamage()];
			this.MaxOres = this.modeMeta.stackSize;
			if (this.stack != null && this.MaxOres < this.stack.stackSize) {//アイテムがあふれたときの処理
				ItemStack dropStack = this.stack.copy();
				dropStack.stackSize = this.stack.stackSize - this.MaxOres;
				this.stack.stackSize = this.MaxOres;
				dropItems(dropStack);
			}
			return retItemStack;
		} else {
			ItemStack retItemStack = this.modeMeta == null ? null : new ItemStack(AntiMatterModRegistry.clayCruciblePattern, 1, this.modeMeta.ordinal());
			this.modeMeta = null;
			this.MaxOres = 9;
			if (this.stack != null && this.MaxOres < this.stack.stackSize) {//アイテムがあふれたときの処理
				ItemStack dropStack = this.stack.copy();
				dropStack.stackSize = this.stack.stackSize - this.MaxOres;
				this.stack.stackSize = this.MaxOres;
				dropItems(dropStack);
			}
			return retItemStack;
		}
	}
	
	private void dropItems(ItemStack dropStack) {
		if (!this.worldObj.isRemote && this.worldObj.getGameRules().getGameRuleBooleanValue("doTileDrops") && !this.worldObj.restoringBlockSnapshots) {
			float f = 0.7F;
			double d0 = (double) (this.worldObj.rand.nextFloat() * f) + (double) (1.0F - f) * 0.5D;
			double d1 = (double) (this.worldObj.rand.nextFloat() * f) + (double) (1.0F - f) * 0.5D;
			double d2 = (double) (this.worldObj.rand.nextFloat() * f) + (double) (1.0F - f) * 0.5D;
			EntityItem entityItem = new EntityItem(this.worldObj, (double) this.xCoord + d0, (double) this.yCoord + d1, (double) this.zCoord + d2, dropStack);
			entityItem.delayBeforeCanPickup = 10;
			this.worldObj.spawnEntityInWorld(entityItem);
		}
	}
	
	public ItemStack getStack() {
		return this.stack;
	}
	
	public ClayCrucibleState getState() {
		return this.state;
	}
	
	public int getMaxOres() {
		return this.MaxOres;
	}
	
	@SuppressWarnings("WeakerAccess")
	public enum ClayCrucibleState {
		NONE,
		HEATING,
		MELTED,
		SOLIDIFIED,
	}
	
} public class BlockSatStove extends BlockContainer {

    public BlockSatStove(){
        super(Material.rock);
        setBlockName("satStove");
        setHardness(2.0f);
        setResistance(0.0f);
    }

    //trueで不透過になる
    @Override
    public boolean isOpaqueCube() {
        return false;
    }

    //独自レンダーの使用時は-1
    public int getRenderType(){
        return -1;
    }

    //レンダーが普通と違うよってこと
    @Override
    public boolean renderAsNormalBlock() {
        return false;
    }

    //Entityの作成
    @Override
    public TileEntity  createNewTileEntity(World var1, int var2){
        return new TileEntitySatStove();
    }
} public class BedrockOreBlock extends Block implements AMMOreBlock{
	
	
	private Block dropBlock = null;
	
	/**
	 * 岩盤鉱石の追加
	 * @param name 鉱石名
	 * @param block 対応する鉱石ブロック
	 */
	public BedrockOreBlock(String name, @NotNull Block block){
		super(Material.rock);
		if(!(block instanceof AMMOreBlock))throw new IllegalArgumentException("渡されたBlockインスタンスはAMMOreBlockをimportしていません");
		this.setBlockName(name);
		this.setBlockTextureName(AntiMatterModCore.MOD_ID+":ore/bedrockore");
		this.setCreativeTab(AntiMatterModRegistry.tabOreBlock);
		this.setResistance(1.0F);
		this.setHardness(3.0F);
		this.setHarvestLevel("pickaxe",3);
		this.setStepSound(Block.soundTypeStone);
		dropBlock = block;
		
	}
	
	@Override
	public Item getItemDropped(int meta, Random random, int fortune) {
			return dropBlock.getItemDropped(meta,random,fortune);
	}
	
	@Override
	public int damageDropped(int meta) {
		return dropBlock.damageDropped(meta);
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public void getSubBlocks(Item item, CreativeTabs tab, List list) {
		for(int i = 0; i < ((AMMOreBlock)dropBlock).getMaxMetadate(); i++){
			list.add(new ItemStack(item, 1, i));
		}
	}
	
	@Override
	public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z, boolean willHarvest) {
		if(player.capabilities.isCreativeMode){
			return super.removedByPlayer(world, player, x, y, z, willHarvest);
		}else if(hasSilkTouch(player.getHeldItem())){
			return super.removedByPlayer(world, player, x, y, z, willHarvest);
		} else{
			//noinspection SimplifiableIfStatement
			if (world.rand.nextInt(100) >= 90+world.rand.nextInt(5)){
				return super.removedByPlayer(world, player, x, y, z, willHarvest);
			}else{
				return true;
			}
		}
	}
	
	/**
	 * silkタッチを持っているかのチェック
	 * @param item 確認するアイテム
	 * @return 持っていたらtrue
	 */
	@SuppressWarnings("WeakerAccess")
	public static boolean hasSilkTouch(ItemStack item){
		NBTTagList list = item.getEnchantmentTagList();
		if (list == null) return false;
		
		for (int i = 0; i < list.tagCount(); i++){
			if(list.getCompoundTagAt(i).getShort("id")==33) return true;
		}
		return false;
	}
	
	@Override
	public int quantityDropped(int meta, int fortune, Random random){
		if(dropBlock instanceof DifferentOreBlock){
			return dropBlock.quantityDropped(meta,fortune,random);
		}
		
		int j = random.nextInt(fortune + 1) - 1;
		
		if (j < 0) {
			j = 0;
		}
		return dropBlock.quantityDropped(random) * (j + 1);
	}
	
	@Override
	public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z, EntityPlayer player) {
		Item item = getItem(world, x, y, z);
		
		if (item == null)
		{
			return null;
		}
		return new ItemStack(item, 1, world.getBlockMetadata(x,y,z));
	}
	
	@Override
	public int getExpDrop(IBlockAccess world, int metadata, int fortune) {
		return this.dropBlock.getExpDrop(world, metadata, fortune);
	}
	
	@Override
	public int getMaxMetadate() {
		return ((AMMOreBlock)this.dropBlock).getMaxMetadate();
	}
} public class ClayCruciblePattern extends Item {
	
	private IIcon[] icons;
	
	public ClayCruciblePattern() {
		this.setUnlocalizedName("clayCruciblePattern");
		this.setTextureName(AntiMatterModCore.MOD_ID + ":ccpattern/");
		this.setCreativeTab(AntiMatterModRegistry.tabMachines);
		this.setMaxStackSize(1);
		icons = new IIcon[ClayCruciblePatternList.values().length];
	}
	
	@Override
	@SideOnly(Side.CLIENT)
	public void registerIcons(IIconRegister register) {
		for (int i = 0; i < icons.length; i++) {
			this.icons[i] = register.registerIcon(this.getIconString() + "_" + i);
		}
	}
	
	@SuppressWarnings("unchecked")
	@Override
	@SideOnly(Side.CLIENT)
	public void getSubItems(Item item, CreativeTabs tab, List list) {
		for (int i = 0; i < icons.length; i++) {
			list.add(new ItemStack(this, 1, i));
		}
	}
	
	@Override
	public int getMetadata(int meta) {
		return meta;
	}
	
	@Override
	public String getUnlocalizedName(ItemStack itemStack) {
		return super.getUnlocalizedName() + "_" + itemStack.getItemDamage();
	}
	
	public enum ClayCruciblePatternList {
		HammerHead(6, AntiMatterModRegistry.iron_tool_material, 0),
		ScrewDriverHead(2, AntiMatterModRegistry.iron_tool_material, 1),
		PickaxeHead(3, AntiMatterModRegistry.iron_tool_material, 2),
		ShovelHead(1, AntiMatterModRegistry.iron_tool_material, 3),
		SwordBlade(2, AntiMatterModRegistry.iron_tool_material, 4),;
		
		public final int stackSize;
		public final Item completionItem;
		public final int itemMeta;
		
		ClayCruciblePatternList(int stackSize, Item completionItem, int itemMeta) {
			this.stackSize = stackSize;
			this.completionItem = completionItem;
			this.itemMeta = itemMeta;
		}
	}
	
} public class MetaItemBlock extends ItemBlock {
	
	public MetaItemBlock(Block block) {
		super(block);
		this.setMaxDamage(0);
		this.setHasSubtypes(true);
		
	}
	
	@Override
	public int getMetadata(int meta) {
		return meta;
	}
	
	@Override
	public String getUnlocalizedName(ItemStack stack) {
		return super.getUnlocalizedName() + "_" + stack.getItemDamage();
		
	}
	
} public class DifferentOreBlock extends OreBlock{

	private static Random random = new Random();
	
	private int[] doropmeta;
	
	private Item doropitems;
	
	private int[] dropQuantitys;
	
	/**
	 * ドロップアイテムが鉱石ブロックじゃないブロックの追加
	 * @param material 材質
	 * @param name ブロック名
	 * @param baseTextureName ベーステクスチャ名
	 * @param handle ベーステクスチャの適応判定数値(2進数表記で1になるところのメタ値と対応したメタがベーステクスチャが反映される)
	 * @param overlayTextureName 鉱石テクスチャ名(いわゆる鉱石が露出してたりするところ)
	 * @param tabs タブ
	 * @param maxMeta メタデータ最大値(1~16)
	 * @param herdness 硬さの配列
	 * @param harvestLevels 採掘レベルの配列
	 * @param doropitems ドロップアイテムのインスタンス
	 * @param doropmeta ブロックのメタ値に対応するドロップするアイテムのメタ値
	 */
	public DifferentOreBlock(Material material, String name, String baseTextureName, int handle, String overlayTextureName, CreativeTabs tabs, int maxMeta, float[] herdness, byte[] harvestLevels, Item doropitems, int [] doropmeta) {
		super(material,name,baseTextureName,handle,overlayTextureName,tabs,maxMeta,herdness,harvestLevels);
		this.doropmeta = doropmeta;
		this.doropitems = doropitems;
	}
	
	/**
	 * ドロップアイテムが鉱石ブロックじゃないブロックの追加
	 * @param material 材質
	 * @param name ブロック名
	 * @param baseTextureName ベーステクスチャ名
	 * @param handle ベーステクスチャの適応判定数値(2進数表記で1になるところのメタ値と対応したメタがベーステクスチャが反映される)
	 * @param overlayTextureName 鉱石テクスチャ名(いわゆる鉱石が露出してたりするところ)
	 * @param tabs タブ
	 * @param maxMeta メタデータ最大値(1~16)
	 * @param herdness 硬さの配列
	 * @param harvestLevels 採掘レベルの配列
	 * @param doropitems ドロップアイテムのインスタンス
	 * @param doropmeta ブロックのメタ値に対応するドロップするアイテムのメタ値
	 * @param dropQuantity ドロップ量(これだけ配列の長さはmaxMeta×2 {基本ドロップ量,最大加算ドロップ量...})
	 */
	public DifferentOreBlock(Material material, String name, String baseTextureName, int handle, String overlayTextureName, CreativeTabs tabs, int maxMeta, float[] herdness, byte[] harvestLevels, Item doropitems, int[] doropmeta, int[] dropQuantity){
		this(material,name,baseTextureName,handle,overlayTextureName,tabs,maxMeta,herdness,harvestLevels,doropitems,doropmeta);
		this.dropQuantitys = dropQuantity;
	}
	
	/**
	 * ドロップアイテムが鉱石ブロックじゃないブロックの追加
	 * @param material 材質
	 * @param name ブロック名
	 * @param overlayTextureName 鉱石テクスチャ名(いわゆる鉱石が露出してたりするところ)
	 * @param tabs タブ
	 * @param maxMeta メタデータ最大値(1~16)
	 * @param herdness 硬さの配列
	 * @param harvestLevels 採掘レベルの配列
	 * @param doropitems ドロップアイテムのインスタンス
	 * @param doropmeta ブロックのメタ値に対応するドロップするアイテムのメタ値
	 */
	public DifferentOreBlock(Material material, String name, String overlayTextureName, CreativeTabs tabs, int maxMeta, float[] herdness, byte[] harvestLevels, Item doropitems, int[] doropmeta){
		this(material,name,null,0,overlayTextureName,tabs,maxMeta,herdness,harvestLevels,doropitems,doropmeta);
	}
	
	/**
	 * ドロップアイテムが鉱石ブロックじゃないブロックの追加
	 * @param material 材質
	 * @param name ブロック名
	 * @param overlayTextureName 鉱石テクスチャ名(いわゆる鉱石が露出してたりするところ)
	 * @param tabs タブ
	 * @param maxMeta メタデータ最大値(1~16)
	 * @param herdness 硬さの配列
	 * @param harvestLevels 採掘レベルの配列
	 * @param doropitems ドロップアイテムのインスタンス
	 * @param doropmeta ブロックのメタ値に対応するドロップするアイテムのメタ値
	 * @param dropQuantity ドロップ量(これだけ配列の長さはmaxMeta×2 {基本ドロップ量,最大加算ドロップ量...})
	 */
	public DifferentOreBlock(Material material, String name, String overlayTextureName, CreativeTabs tabs, int maxMeta, float[] herdness, byte[] harvestLevels, Item doropitems, int[] doropmeta, int[] dropQuantity){
		this(material,name,null,0,overlayTextureName,tabs,maxMeta,herdness,harvestLevels,doropitems,doropmeta);
		this.dropQuantitys = dropQuantity;
	}
	
	/**
	 * ドロップアイテムが鉱石ブロックじゃないブロックの追加
	 * @param material 材質
	 * @param name ブロック名
	 * @param baseTextureNames ベーステクスチャの名前配列
	 * @param overlayTextureName 鉱石テクスチャ名(いわゆる鉱石が露出してたりするところ)
	 * @param tabs タブ
	 * @param maxMeta メタデータ最大値(1~16)
	 * @param herdness 硬さの配列
	 * @param harvestLevels 採掘レベルの配列
	 * @param doropitems ドロップアイテムのインスタンス
	 * @param doropmeta ブロックのメタ値に対応するドロップするアイテムのメタ値
	 * @deprecated まだテクスチャの判定がされない。
	 */
	@Deprecated
	public DifferentOreBlock(Material material, String name, String baseTextureNames[], String overlayTextureName, CreativeTabs tabs, int maxMeta, float[] herdness, byte[] harvestLevels, Item doropitems, int[] doropmeta) {
		super(material, name, baseTextureNames, overlayTextureName, tabs, maxMeta, herdness, harvestLevels);
		this.doropmeta = doropmeta;
		this.doropitems = doropitems;
	}
	
	
	@Override
	protected boolean canSilkHarvest() {
		return true;
	}
	
	@Override
	public int getExpDrop(IBlockAccess world, int metadata, int fortune) {
		return MathHelper.getRandomIntegerInRange(random, 7, 10+(fortune*3));
	}
	
	@Override
	public Item getItemDropped(int meta, Random random, int fortune) {
		return this.doropitems;
	}
	
	@Override
	public int damageDropped(int meta) {
		return this.doropmeta[meta];
	}
	
	@Override
	public int quantityDropped(int meta, int fortune, Random random) {
		int i = random.nextInt(fortune + 2) - 1;
		if(i < 0) i = 0;
		return this.quantityDropped(meta,random) * (i + 1);
	}
	
	public int quantityDropped(int meta,Random p_149745_1_) {
		if(this.dropQuantitys == null){
			return 1;
		}else {
			if(this.dropQuantitys.length < meta*2) return 1;
			int quantity = this.dropQuantitys[meta*2];
			quantity += this.dropQuantitys[meta*2+1] > 0 ? p_149745_1_.nextInt(this.dropQuantitys[meta*2+1]+1) : 0;
			return quantity;
		}
	}
	
	@Override
	public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z, EntityPlayer player) {
		Item item = getItem(world, x, y, z);

		if (item == null)
		{
			return null;
		}
		return new ItemStack(item, 1, world.getBlockMetadata(x,y,z));
	}
} public class OreBlock extends OverlayBlockBase implements AMMOreBlock{

    private String overlayTextureName;

    private IIcon[] Overlaytextures;
    
    private String[] baseTextureNames;
    
    private IIcon[] baseTextures;

    private float[] herdness;

    private byte[] harvestLevels;

    private short handle;
    
    /**
     * 同化する鉱石ブロックを追加
     * @param material 材質
     * @param name 名前
     * @param baseTextureName テクスチャ名
     * @param handle ベーステクスチャの適応判定数値(2進数表記で1になるところのメタ値と対応したメタがベーステクスチャが反映される)
     * @param overlayTextureName 鉱石テクスチャ名(いわゆる鉱石が露出してたりするところ)
     * @param tabs タブ
     * @param maxMeta メタデータ最大値(1~16)
     * @param herdness 硬さの配列
     * @param harvestLevels 採掘レベルの配列
     */
    public OreBlock(Material material, String name, String baseTextureName, int handle, String overlayTextureName, CreativeTabs tabs, int maxMeta, float[] herdness, byte[] harvestLevels){
        super(material);
        this.setBlockName(name);
        if(baseTextureName != null)this.baseTextureNames = new String[]{(AntiMatterModCore.MOD_ID+":"+baseTextureName)};
        this.setOverlayTextureName(AntiMatterModCore.MOD_ID+":"+overlayTextureName);
        if(tabs != null)this.setCreativeTab(tabs);
        this.setResistance(1.0F);
        this.setStepSound(Block.soundTypeStone);
        if(maxMeta > 16)throw new ArrayIndexOutOfBoundsException("メタ値の最大は16までです！！");
        this.Overlaytextures = new IIcon[maxMeta];
        this.herdness = herdness;
        this.harvestLevels = harvestLevels;
        this.handle = (short) handle;
        if(baseTextureName != null) baseTextures = new IIcon[baseTextureNames.length];
    }
    
    /**
     * 同化する鉱石ブロックを追加
     * @param material 材質
     * @param name 名前
     * @param overlayTextureName 鉱石テクスチャ名(いわゆる鉱石が露出してたりするところ)
     * @param tabs タブ
     * @param maxMeta メタデータ最大値(1~16)
     * @param herdness 硬さの配列
     * @param harvestLevels 採掘レベルの配列
     */
    public OreBlock(Material material, String name, String overlayTextureName, CreativeTabs tabs, int maxMeta, float[] herdness, byte[] harvestLevels){
        this(material,name,null,0,overlayTextureName,tabs,maxMeta,herdness,harvestLevels);
    }
    
    /**
     * 同化する鉱石ブロックを追加
     * @param material 材質
     * @param name 名前
     * @param baseTextureNames ベーステクスチャの名前配列
     * @param overlayTextureName 鉱石テクスチャ名(いわゆる鉱石が露出してたりするところ)
     * @param tabs タブ
     * @param maxMeta メタデータ最大値(1~16)
     * @param herdness 硬さの配列
     * @param harvestLevels 採掘レベルの配列
     * @deprecated まだテクスチャの判定がされない。
     */
    @Deprecated
    public OreBlock(Material material, String name, String baseTextureNames[], String overlayTextureName, CreativeTabs tabs, int maxMeta, float[] herdness, byte[] harvestLevels) {
        this(material, name, null, 0, overlayTextureName, tabs, maxMeta, herdness, harvestLevels);
        this.baseTextureNames = baseTextureNames;
        this.baseTextures = new IIcon[baseTextureNames.length];
    }

    @Override
    public float getBlockHardness(World world, int x, int y, int z) {
        return this.herdness[world.getBlockMetadata(x,y,z)];
    }

    @Override
    public float getExplosionResistance(Entity par1Entity, World world, int x, int y, int z, double explosionX, double explosionY, double explosionZ) {
        return this.herdness[world.getBlockMetadata(x,y,z)];
    }

    @Override
    public int getHarvestLevel(int metadata) {
        return harvestLevels[metadata];
    }

    @Override
    public String getHarvestTool(int metadata) {
        return "pickaxe";
    }

    @Override
    public int damageDropped(int meta) {
        return meta;
    }

    @SuppressWarnings("unchecked")
    @Override
    @SideOnly(Side.CLIENT)
    public void getSubBlocks(Item item, CreativeTabs tab, List list) {
        for (int i = 0; i < this.Overlaytextures.length; i++) {
            list.add(new ItemStack(item, 1, i));
        }
    }

    @Override
    public void registerBlockIcons(IIconRegister iiconregister) {
        super.registerBlockIcons(iiconregister);
        for (int i = 0; i < this.Overlaytextures.length; i++) {
            this.Overlaytextures[i] = iiconregister.registerIcon(this.getOverlayTextureName()+"_"+i);
        }
        if(this.baseTextures == null)return;
        for (int i = 0; i < this.baseTextures.length; i++) {
            this.baseTextures[i] = iiconregister.registerIcon(baseTextureNames[i]);
        }
    }

    public void setOverlayTextureName(String overlayTextureName) {
        this.overlayTextureName = overlayTextureName;
    }

    public String getOverlayTextureName() {
        return overlayTextureName;
    }
    
    @Override
    public IIcon getBaseIcon(IBlockAccess world, int x, int y, int z) {
        return getBaseIcon(world, x, y, z, null, 0, new ArrayList<>());
    }
    
    public IIcon getBaseIcon(IBlockAccess world, int x, int y, int z, ForgeDirection chain, int count, ArrayList<Point> poitList) {
        if (this.baseTextures != null){
            int meta = world.getBlockMetadata(x,y,z);
            if(this.handle != 0){
                String binary = Integer.toBinaryString(this.handle);
                if (binary.length() > meta && binary.charAt(meta) == '1'){
                    return this.baseTextures[0];
                }
            }
        }
        IIcon icon = getTouchingBlockIcon(world,x,y,z,isTouchingBlock(world,x,y,z,ReversalForgeDirection(chain),poitList),count,poitList);
        return icon != null ? icon : Blocks.stone.getIcon(0,0);
    }
    
    public static ForgeDirection isTouchingBlock(IBlockAccess world, int x, int y, int z, ForgeDirection chain,ArrayList<Point> pointList){
        ForgeDirection oreBlocktouvhing = null;
        if(world.getBlock(x,y+1,z) != Blocks.air){
            if(!(world.getBlock(x,y+1,z) instanceof OreBlock)) {
                return ForgeDirection.UP;
            }
            if (chain != ForgeDirection.UP && !Point.isOnPoint(pointList,x,y+1,z))oreBlocktouvhing = ForgeDirection.UP;
        }
        if(world.getBlock(x,y,z-1) != Blocks.air){
            if(!(world.getBlock(x,y,z-1) instanceof OreBlock)) {
                return ForgeDirection.NORTH;
            }
            if (chain != ForgeDirection.NORTH && !Point.isOnPoint(pointList,x,y,z-1))oreBlocktouvhing = ForgeDirection.NORTH;
        }
        if(world.getBlock(x,y,z+1) != Blocks.air){
            if(!(world.getBlock(x,y,z+1) instanceof OreBlock)) {
                return ForgeDirection.SOUTH;
            }
            if (chain != ForgeDirection.SOUTH && !Point.isOnPoint(pointList,x,y,z+1))oreBlocktouvhing = ForgeDirection.SOUTH;
        }
        if(world.getBlock(x-1,y,z) != Blocks.air){
            if(!(world.getBlock(x-1,y,z) instanceof OreBlock)) {
                return ForgeDirection.WEST;
            }
            if (chain != ForgeDirection.WEST && !Point.isOnPoint(pointList,x-1,y,z))oreBlocktouvhing = ForgeDirection.WEST;
        }
        if(world.getBlock(x+1,y,z) != Blocks.air){
            if(!(world.getBlock(x+1,y,z) instanceof OreBlock)) {
                return ForgeDirection.EAST;
            }
            if (chain != ForgeDirection.EAST && !Point.isOnPoint(pointList,x+1,y,z))oreBlocktouvhing = ForgeDirection.EAST;
        }
        if(world.getBlock(x,y-1,z) != Blocks.air){
            if(!(world.getBlock(x,y-1,z) instanceof OreBlock)) {
                return ForgeDirection.DOWN;
            }
            if (chain != ForgeDirection.DOWN && !Point.isOnPoint(pointList,x,y-1,z))oreBlocktouvhing = ForgeDirection.DOWN;
        }
        
        return oreBlocktouvhing;
    }
    
    
    public static IIcon getTouchingBlockIcon(IBlockAccess world, int x, int y, int z, ForgeDirection dir, int count, ArrayList<Point> pointList){
        if(dir == null) return null;
        Block block = world.getBlock(x+dir.offsetX,y+dir.offsetY,z+dir.offsetZ);
        if(block == Blocks.stone || block == Blocks.netherrack || block == Blocks.end_stone){
            return block.getIcon(0,0);
        }else if(block instanceof OreBlock){
            count++;
            pointList.add(new Point(x,y,z));
            return ((OreBlock)block).getBaseIcon(world, x+dir.offsetX, y+dir.offsetY, z+dir.offsetZ,dir, count, pointList);
        }
        return null;
    }
    
    @Override
    public IIcon getBaseIcon(int meta) {
        if(this.baseTextureNames != null){
            if(this.handle != 0){
                String binary = Integer.toBinaryString(this.handle);
                if(binary.length() > meta && binary.charAt(meta) == '1'){
                    return this.baseTextures[0];
                }
            }
        }
        return Blocks.stone.getIcon(0,0);
    }
    
    public static ForgeDirection ReversalForgeDirection(ForgeDirection dir){
        if (dir == null) return null;
        switch (dir){
            case UP:
                return ForgeDirection.DOWN;
            case DOWN:
                return ForgeDirection.UP;
            case EAST:
                return ForgeDirection.WEST;
            case WEST:
                return ForgeDirection.EAST;
            case NORTH:
                return ForgeDirection.SOUTH;
            case SOUTH:
                return ForgeDirection.NORTH;
            default:
                return null;
        }
    }
    
    @Override
    public IIcon getIcon(int par, int meta) {
        return Overlaytextures[meta];
    }
    
    @Override
    public int getMaxMetadate() {
        return Overlaytextures.length;
    }
} public class Marmite extends ItemFood{

    private static int foodID_01=29000;

    public Marmite(String texture){
        //第一引数にID,第二引数に回復量,第三引数はオオカミが食べれるかどうか
        super(1000,200,false);
        setCreativeTab(AntiMatterModRegistry.tabMaterials);
        setTextureName(AntiMatterModCore.MOD_ID+":"+"/food/"+texture);
        setUnlocalizedName("marmite");
        setAlwaysEdible();
    }

} public class EntityHoeHoeMan extends EntityMob implements IBossDisplayData {

    public EntityHoeHoeMan(World world){
        super(world);
        tasks.addTask(1,new EntityAISwimming(this));
        tasks.addTask(2,new EntityAIAttackOnCollide(this, EntityPlayer.class,100,true));
        tasks.addTask(3,new EntityAIWander(this,1.0D));
        targetTasks.addTask(1,new EntityAINearestAttackableTarget(this,EntityPlayer.class,0,true));
        targetTasks.addTask(2,new EntityAIHurtByTarget(this,false));
    }

    @Override
    protected void applyEntityAttributes(){
        super.applyEntityAttributes();
        getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(60D);
        getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(1280D);
        getEntityAttribute(SharedMonsterAttributes.knockbackResistance).setBaseValue(3000);
        getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(3000);
        getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(3);
    }
} public class ItemHoeHoeManEgg extends Item {

    public ItemHoeHoeManEgg(){
        super();
        setUnlocalizedName("itemHoeHoeManEgg");
        setCreativeTab(AntiMatterModRegistry.tabTools);
        setTextureName("");
    }

    @Override
    public boolean onItemUse(ItemStack itemStack, EntityPlayer player, World world, int x, int y, int z, int side, float posX, float posY, float posZ)
    {
        //サーバー側の場合は処理をスキップする
        if (world.isRemote)
        {
            return true;
        }
        else
        {
            Block block = world.getBlock(x, y, z);
            x += Facing.offsetsXForSide[side];
            y += Facing.offsetsYForSide[side];
            z += Facing.offsetsZForSide[side];
            double height = 0.0D;

            if (side == 1 && block.getRenderType() == 11)
            {
                height = 0.5D;
            }

            Entity entity = spawnEntity(world, (double)x + 0.5D, (double)y + height, (double)z + 0.5D);

            if (entity != null)
            {

                if (!player.capabilities.isCreativeMode)
                {
                    --itemStack.stackSize;
                }
            }

            return true;
        }
    }

    /**アイテムを使ったときのメソッド。ItemMonsterPlacer参照。*/
    @Override
    public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityPlayer player)
    {
        //サーバー側の場合は処理をスキップする
        if (world.isRemote)
        {
            return itemStack;
        }
        else
        {
            MovingObjectPosition movingobjectposition = this.getMovingObjectPositionFromPlayer(world, player, true);

            if (movingobjectposition == null)
            {
                return itemStack;
            }
            else
            {
                if (movingobjectposition.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK)
                {
                    int x = movingobjectposition.blockX;
                    int y = movingobjectposition.blockY;
                    int z = movingobjectposition.blockZ;

                    if (!world.canMineBlock(player, x, y, z))
                    {
                        return itemStack;
                    }

                    if (!player.canPlayerEdit(x, y, z, movingobjectposition.sideHit, itemStack))
                    {
                        return itemStack;
                    }

                    if (world.getBlock(x, y, z) instanceof BlockLiquid)
                    {
                        Entity entity = spawnEntity(world, (double)x, (double)y, (double)z);

                        if (entity != null)
                        {
                            if (!player.capabilities.isCreativeMode)
                            {
                                --itemStack.stackSize;
                            }
                        }
                    }
                }

                return itemStack;
            }
        }
    }


    public Entity spawnEntity(World world, double x, double y, double z)
    {
        EntityHoeHoeMan entityliving = new EntityHoeHoeMan(world);
        entityliving.setLocationAndAngles(x, y, z, MathHelper.wrapAngleTo180_float(world.rand.nextFloat() * 360.0F), 0.0F);
        entityliving.rotationYawHead = entityliving.rotationYaw;
        entityliving.renderYawOffset = entityliving.rotationYaw;
        entityliving.onSpawnWithEgg((IEntityLivingData)null);
        world.spawnEntityInWorld(entityliving);
        entityliving.playLivingSound();
        return entityliving;
    }

} public class RenderHoeHoeMan extends RenderLiving {

    public RenderHoeHoeMan(){
        super(new ModelHoeHoeMan(),0.5f);
    }

    @Override
    protected ResourceLocation getEntityTexture(Entity entity){
        return new ResourceLocation(AntiMatterModCore.MOD_ID+":textures/mobs/HoeHoeMan.png");
    }

    public void doRender(EntityHoeHoeMan entity,double d0,double d1,double d2,float f0,float f1){
        BossStatus.setBossStatus(entity,false);
        super.doRender((EntityLiving)entity,d0,d1,d2,f0,f1);
    }

    public void doRender(EntityLivingBase livingBase,double d0,double d1,double d2,float f0, float f1){
        this.doRender((EntityHoeHoeMan)livingBase,d0,d1,d2,f0,f1);
    }

    public void doRender(EntityLiving living,double d0, double d1,double d2,float f0,float f1){
        this.doRender((EntityHoeHoeMan)living,d0,d1,d2,f0,f1);
    }
} public enum AMMToolMaterial {
	@CraftingToolProperty(maxUse = 10, level = 0)IRON(ToolMaterial.IRON),
	DIAMOND(ToolMaterial.EMERALD),
	//Raitium(3, 250, 8.0F, 3.0F, 14, new ItemStack(AntiMatterModRegistry.ingot_01, 1, 1)),
	//Drantium(3, 250, 6.0F, 2.0F, 22, new ItemStack(AntiMatterModRegistry.ingot_01, 1, 2)),
	//Palazirite(3, 400, 6.0F, 2.0F, 14, new ItemStack(AntiMatterModRegistry.ingot_01, 1, 3)),
	
	;
	//==================================================================================================================
	
	AMMToolMaterial(int harvestLevel, int maxUse, float efficiency, float damage, int enchantAbility) {
		this.toolMaterial = EnumHelper.addToolMaterial(this.toString(), harvestLevel, maxUse, efficiency, damage, enchantAbility);
		this.annotationHandle();
	}
	
	AMMToolMaterial(ToolMaterial material) {
		this.toolMaterial = material;
		this.annotationHandle();
	}
	
	AMMToolMaterial(int harvestLevel, int maxUse, float efficiency, float damage, int enchantAbility, ItemStack repairItem) {
		this(harvestLevel, maxUse, efficiency, damage, enchantAbility);
		this.toolMaterial.setRepairItem(repairItem);
	}
	
	private ToolMaterial toolMaterial;
	
	public ToolMaterial getToolMaterial() {
		return toolMaterial;
	}
	
	private int craftingToolMaxUse;
	public int getCraftingToolMaxUse() {
		return craftingToolMaxUse;
	}
	
	private int craftingToolLevel = -1;
	public int getCraftingToolLevel() {
		return craftingToolLevel;
	}
	
	private void annotationHandle() {
		Class<? extends AMMToolMaterial> materialClass = this.getClass();
		try {
			Field field = materialClass.getField(this.name());
			
			//----------------------------------------------------------------------------------------------------------
			CraftingToolProperty cToolProperty = field.getAnnotation(CraftingToolProperty.class);
			if (cToolProperty != null) {
				this.craftingToolMaxUse = cToolProperty.maxUse();
				this.craftingToolLevel = cToolProperty.level();
			} else this.craftingToolMaxUse = toolMaterial.getMaxUses() / 10;
			//----------------------------------------------------------------------------------------------------------
			
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		}
	}
	
	@Retention(RetentionPolicy.RUNTIME)
	@Target(ElementType.FIELD)
	public @interface CraftingToolProperty {
		int maxUse();
		
		int level();
	}
	
} @FunctionalInterface
public interface AddInformationfunction {

    /**
     * 情報を追加する処理
     * playerに判定をつけると、この人だけにこの情報とか、<br>
     * 表示させた人の名前を表示とかができる
     *
     * @param item       トリガーアイテム
     * @param player     情報を表示させようとしたプレイヤー
     * @param list       情報を格納するリスト、要素1つにつき1行
     * @param p_77624_4_ F3+H キーが有効か
     */
    void addInformation(ItemStack item, EntityPlayer player, List list, boolean p_77624_4_);

    /**
     * {@link AntiMatterModRegistry#ingot_01}の情報
     */
    @SuppressWarnings("unchecked")
    static void IngotInformation(ItemStack item, @SuppressWarnings("unused") EntityPlayer player, List list, @SuppressWarnings("unused") boolean isdebug) {
        switch (item.getItemDamage()) {
            case 0:
                list.add(StatCollector.translateToLocal("tile.ingot_01_0.information_1"));
                list.add(StatCollector.translateToLocal("tile.ingot_01_0.information_2"));
                list.add(ChatFormatting.RED + StatCollector.translateToLocal("tile.ingot_01_0.information.name"));
                break;
        }
    }
    @SuppressWarnings("unchecked")
    static void authorIngotInfo(ItemStack item, @SuppressWarnings("unused") EntityPlayer player, List list, @SuppressWarnings("unused") boolean isdebug) {
        switch (item.getItemDamage()) {
            case 0:
                list.add(StatCollector.translateToLocal("tile.authorIngot>6.information") + AntiMatterModCore.modMetadata.authorList.get(1));
                break;
            case 1:
                list.add(StatCollector.translateToLocal("tile.authorIngot>6.information") + AntiMatterModCore.modMetadata.authorList.get(2));
                break;
            case 2:
                list.add(StatCollector.translateToLocal("tile.authorIngot>6.information") + AntiMatterModCore.modMetadata.authorList.get(0));
                break;
            case 3:
                list.add(StatCollector.translateToLocal("tile.authorIngot>6.information") + AntiMatterModCore.modMetadata.authorList.get(3));
                break;
            case 4:
                list.add(StatCollector.translateToLocal("tile.authorIngot>6.information") + AntiMatterModCore.modMetadata.authorList.get(4));
                break;
            case 5:
                list.add(StatCollector.translateToLocal("tile.authorIngot>6.information") + "Emilin");
                break;
        }
    }

    @SuppressWarnings("unchecked")
    static void WrenchInformation(ItemStack item, @SuppressWarnings("unused") EntityPlayer player, List list, @SuppressWarnings("unused") boolean isdebug) {
        if (item.getItem() instanceof ItemWrench) {
            if (item.hasTagCompound()) {
                list.add(StatCollector.translateToLocal("item.wrench.mode") + ":" + StatCollector.translateToLocal("wrench.mode.name." + (WrenchMode.values()[item.getTagCompound().getInteger("WrenchMode")]).toString()));
                //list.add("Mode:" + (WrenchMode.values()[item.getTagCompound().getInteger("WrenchMode")]).toString());
            }
        }
    }

} public class BlockUtil {

    /**
     * 無機能なブロックを追加します
     * @param name ブロック名
     * @param textureName テクスチャ―名
     * @param material 材質
     * @param hardness 硬さ
     * @param resistance 耐爆値
     * @return Blockオブジェクト
     */
    public static Block CreateBlock(@NotNull String name, @Nullable String textureName, @NotNull Material material, float hardness, float resistance){
        Block block = new SimpleBlock(material);
        block.setHardness(hardness);
        block.setResistance(resistance);
        block.setBlockName(name);
        if(textureName == null || textureName.isEmpty()){
            textureName = name;
        }
        textureName = AntiMatterModCore.MOD_ID + textureName;
        block.setBlockTextureName(textureName);
        return block;
    }

    /**
     * 無機能なメタデータ持ちブロックを追加します。
     * メタ値による硬さ、耐爆値の変更はできません
     * @param name ブロック名
     * @param textureName テクスチャ―名
     * @param material 素材名
     * @param tab 追加タブ
     * @param maxMeta メタデータ最大値 1~16
     * @param hardness ブロックの硬さ
     * @param resistance 耐爆値
     * @return Blockオブジェクト
     */
    public static Block CreateBlock(@NotNull String name, @NotNull String textureName, @NotNull Material material, @Nullable CreativeTabs tab, int maxMeta, float hardness, float resistance){
        Block block = new SimpleMetaBlock(material,maxMeta);
        block.setHardness(hardness);
        block.setResistance(resistance);
        block.setBlockName(name);
        if(textureName == null || textureName.isEmpty()){
            textureName = name;
        }
        if(tab != null) block.setCreativeTab(tab);
        textureName = AntiMatterModCore.MOD_ID + ":" + textureName;
        block.setBlockTextureName(textureName);
        return block;
    }
} public class ItemUtil {
	/**
	 * 無機能なアイテムオブジェクトを作成します<br>
	 * @param name アイテム名 {@link Item#setUnlocalizedName(String)}
	 * @param textureName テクスチャ―名 {@link Item#setTextureName(String)}
	 * @param addTab 追加タブ {@link Item#setCreativeTab(CreativeTabs)}
	 * @param stackSize 最大スタックサイズ {@link Item#setMaxStackSize(int)}
	 * @param hasSubtype メタ値でアイテムが分けられているか {@link Item#setHasSubtypes(boolean)}
	 * @param maxMeta
	 * @param isFull3D アイテムを3Dで表示するか {@link Item#isFull3D()}
	 * @param containerItem クラフト時に帰ってくるアイテム {@link Item#setContainerItem(Item)}
	 * @return アイテムオブジェクト
	 */
	public static Item CreateItem(@NotNull String name , @Nullable String textureName ,@Nullable CreativeTabs addTab ,int stackSize , boolean hasSubtype ,
								  int maxMeta , boolean isFull3D,@Nullable Item containerItem) {
		
		Item item = hasSubtype ? new MetaItem(maxMeta) : new Item();
		item.setUnlocalizedName(name);
		if(textureName == null || textureName.isEmpty()){
			textureName = name;
		}
		item.setTextureName(AntiMatterModCore.MOD_ID+":"+textureName);
		if(addTab != null) item.setCreativeTab(addTab);
		item.setMaxStackSize(stackSize);
		item.setMaxDamage(0);
		if(isFull3D) item.setFull3D();
		if(containerItem != null) item.setContainerItem(containerItem);
		
		return item;
	}
	
	/**
	 * {@link ItemUtil#CreateItem(String, String, CreativeTabs, int, boolean, int, boolean, Item)}のラッパー関数
	 * @param name 名前
	 * @param textureName テクスチャ名
	 * @param maxMeta メタデータ最大値
	 * @param tabs クリエイティブタブ
	 * @return アイテムオブジェクト
	 */
	public static Item CreateItem(@NotNull String name,@NotNull String textureName,int maxMeta,@Nullable CreativeTabs tabs){
		return CreateItem(name, textureName, tabs, 64, true, maxMeta, false, null);
	}
	
	/**
	 * {@link MetaItemBase}クラスを継承したクラスを使用してアイテムを生成します。<br>
	 * 主にツールチップの説明表示などに使います。
	 * @param name アイテム名 {@link Item#setUnlocalizedName(String)}
	 * @param textureName テクスチャ―名 {@link Item#setTextureName(String)}
	 * @param maxMeta 最大メタ値
	 * @param addTab 追加タブ {@link Item#setCreativeTab(CreativeTabs)}
	 * @param addfunc 情報追加関数 {@link AddInformationfunction#addInformation(ItemStack, EntityPlayer, List, boolean)}
	 * @return アイテムオブジェクト
	 */
	public static Item CreateItem(String name, String textureName, int maxMeta, CreativeTabs addTab, AddInformationfunction addfunc) {
		MetaItemBase item = new MetaItemBase(maxMeta, addfunc);
		item.setUnlocalizedName(name);
		item.setTextureName(AntiMatterModCore.MOD_ID+":"+textureName);
		if(addTab != null) item.setCreativeTab(addTab);
		item.setMaxStackSize(64);
		item.setMaxDamage(0);
		return item;
	}
	
} public class OreGenerator implements IWorldGenerator {
	
	
	@Override
	public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) {
		
		if (world.provider instanceof WorldProviderSurface) {
			
			oreGenerateOverworld(random, chunkX, chunkZ, world, chunkGenerator, chunkProvider);
		} else if (world.provider instanceof WorldProviderHell) {
			oreGenerateHell(random, chunkX, chunkZ, world, chunkGenerator, chunkProvider);
		} else if (world.provider instanceof WorldProviderEnd) {
			oreGenerateEnd(random, chunkX, chunkZ, world, chunkGenerator, chunkProvider);
		}
		
		
	}
	
	private void oreGenerateOverworld(Random random, int x, int z, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) {
		for (OreGeneratorEntry entry : OreGeneratorEntry.ORE_GENERATOR_ENTRIES) {
			if (!entry.isGeneratOverworld()) continue;
			
			if (entry.hasGenerateFunction()) {
				OreGeneratorEntry.GenerateFunction function = entry.getGenerateFunction(OreGeneratorEntry.PROPERTY_OVERWORLD);
				if (function != null) {
					function.oreGenerate(random, x, z, world, chunkProvider, chunkGenerator);
					return;
				}
			}
			for (int i = 0; i < entry.getLoop(); i++) {
				int genX = (x << 4) + random.nextInt(16);
				int genY = (entry.getMinYOverworld() + random.nextInt(entry.getMaxYOverworld() - entry.getMinYOverworld()));
				int genZ = (z << 4) + random.nextInt(16);
				entry.getGenMinable().generate(world, random, genX, genY, genZ);
			}
			
		}
		
	}
	
	private void oreGenerateHell(Random random, int x, int z, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) {
		for (OreGeneratorEntry entry : OreGeneratorEntry.ORE_GENERATOR_ENTRIES) {
			if (!entry.isGeneratHell()) continue;
			
			if (entry.hasGenerateFunction()) {
				OreGeneratorEntry.GenerateFunction function = entry.getGenerateFunction(OreGeneratorEntry.PROPERTY_HELL);
				if (function != null) {
					function.oreGenerate(random, x, z, world, chunkProvider, chunkGenerator);
					return;
				}
			}
			for (int i = 0; i < entry.getLoop(); i++) {
				int genX = (x << 4) + random.nextInt(16);
				int genY = (entry.getMinYHell() + random.nextInt(entry.getMaxYHell() - entry.getMinYHell()));
				int genZ = (z << 4) + random.nextInt(16);
				entry.getGenMinable().generate(world, random, genX, genY, genZ);
				
			}
		}
	}
	
	private void oreGenerateEnd(Random random, int x, int z, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) {
		for (OreGeneratorEntry entry : OreGeneratorEntry.ORE_GENERATOR_ENTRIES) {
			if (!entry.isGeneratEnd()) continue;
			
			if (entry.hasGenerateFunction()) {
				OreGeneratorEntry.GenerateFunction function = entry.getGenerateFunction(OreGeneratorEntry.PROPERTY_END);
				if (function != null) {
					function.oreGenerate(random, x, z, world, chunkProvider, chunkGenerator);
					return;
				}
			}
			for (int i = 0; i < entry.getLoop(); i++) {
				int genX = (x << 4) + random.nextInt(16);
				int genY = (entry.getMinYEnd() + random.nextInt(entry.getMaxYEnd() - entry.getMinYEnd()));
				int genZ = (z << 4) + random.nextInt(16);
				entry.getGenMinable().generate(world, random, genX, genY, genZ);
			}
		}
	}
	
	
} public class AMMStructureEventHandler {
	
	//private TestMapGen test = new TestMapGen();
	
	private TiamatMapGen tiamatMapGen = new TiamatMapGen();
	
	// コンストラクタ相当(getModdedMapGen or InitMapGenEvent)相当
	@SubscribeEvent
	@SuppressWarnings("unused")
	public void onInitNoiseGensEvent(InitNoiseGensEvent event){
		
	}
	
	// generateStructuresInChunk相当
	// 要塞や村より前のタイミングならこちら
	// ここで生成すると、要塞や村・溶岩溜まり等の後で生成される地形要素に潰される可能性がある
	//　その代わり村や要塞を避けるような判定は不要
	@SubscribeEvent
	@SuppressWarnings("unused")
	public void onPopulateChunkEvent(PopulateChunkEvent.Pre event){
		// 通常世界(Overworld)にサンプルダンジョンを生成したいのでディメンションIDで通常世界かどうか判断する
		if(event.world.provider.dimensionId == 0){
			// ８チャンク以内に追加構造物生成に適したチャンクがあるかを調べ、ある場合は生成する追加構造物の構成パーツを決定する
			this.tiamatMapGen.func_151539_a(event.chunkProvider, event.world, event.chunkX, event.chunkZ, null);
			
			//追加構造物の一部が このチャンク範囲に重複するかどうかを調べ、重複する場合は追加構造物のブロックをチャンク内に設置する
			this.tiamatMapGen.generateStructuresInChunk(event.world,event.rand,event.chunkX,event.chunkZ);
		}
	}
	
	// generateStructuresInChunk相当
	// 要塞や村より後のタイミングならこちら
	// event.typeにより順番が決まる＆呼ばれなかったりするので注意
	// ここで生成するなら要塞等を潰さないように注意
	@SubscribeEvent
	@SuppressWarnings("unused")
	public void onPopulateChunkEvent(PopulateChunkEvent.Populate event) {
		
	}
	
	// generateStructuresInChunk相当
	// 完全にチャンクの要素が決定された後のタイミングならこちら
	// ここで生成するなら要塞等を潰さないように注意
	@SubscribeEvent
	@SuppressWarnings("unused")
	public void onPopulateChunkEvent(PopulateChunkEvent.Post event) {
		
	}
	
} @SuppressWarnings("unchecked")
public class StructureTestStart extends StructureStart {
	
	public StructureTestStart(){
		
	}
	
	public StructureTestStart(World world, Random random, int par3, int par4){
		super(par3,par4);
		// 構造物の構成パーツを決定する
		// 基点はComponentSampleDungeon1
		ComponentTest1 componentTest1 = new ComponentTest1(0, random, (par3 << 4)+2, (par4 << 4)+2);
		this.components.add(componentTest1);
		
		//次のパーツ
		componentTest1.buildComponent(componentTest1,this.components,random);
		
		List<StructureComponent> list = componentTest1.structureComponents;
		while (!list.isEmpty()){
			int k = random.nextInt(list.size());
			StructureComponent structureComponent = list.remove(k);
			structureComponent.buildComponent(componentTest1,this.components,random);
		}
		this.updateBoundingBox();
	}
	
	
	
	public class ComponentTest1 extends StructureComponent {
		
		public List<StructureComponent> structureComponents = new ArrayList<>();
		
		public ComponentTest1(){
			
		}
		
		public ComponentTest1(int par1, Random random, int par3, int par4){
			this.coordBaseMode = random.nextInt(4);
			switch(this.coordBaseMode) {
				case 0:
				case 1:
				case 2:
				case 3:
				default:
					// 占有範囲を設定(このサンプルではどの方角を向いてても同じ)
					// (x,y,z) = (par3, 64, par4)の地点から4x10x4ブロックが占有範囲
					this.boundingBox = new StructureBoundingBox(par3, 64, par4, par3 + 4, 74, par4 + 4);
					break;
			}
		}
		
		@Override
		public void buildComponent(StructureComponent p_74861_1_, List p_74861_2_, Random p_74861_3_) {
			// 次のパーツはComponentSampleDungeon2を斜めに接続
			StructureComponent structureComponent = new ComponentTest2(0, p_74861_3_, this.boundingBox.maxX + 1, this.boundingBox.maxZ + 1, 0);
			((ComponentTest1)p_74861_1_).structureComponents.add(structureComponent);
			p_74861_2_.add(structureComponent);
		}
		
		@Override
		protected void func_143012_a(NBTTagCompound p_143012_1_) {
			
		}
		
		@Override
		protected void func_143011_b(NBTTagCompound p_143011_1_) {
			
		}
		
		@Override
		public boolean addComponentParts(World p_74875_1_, Random p_74875_2_, StructureBoundingBox p_74875_3_) {
			if(this.isLiquidInStructureBoundingBox(p_74875_1_,p_74875_3_)) return false;
			
			// 占有範囲(structureboundingbox)内の指定範囲を指定ブロック＆メタデータで埋める
			// 占有範囲内の指定範囲は占有範囲原点を基準として(0,0,0)-(4,10,4)の範囲
			this.fillWithMetadataBlocks(p_74875_1_, p_74875_3_, 0, 0, 0, 4, 10, 4, Blocks.stone,0 ,Blocks.air, 0, false);
			
			// 占有範囲(structureboundingbox)内の指定範囲を空気ブロックで埋める
			// 占有範囲内の指定範囲は占有範囲原点を基準として(1,1,1)-(3,9,3)の範囲
			// 要するに中をくりぬいてるってことです
			this.fillWithAir(p_74875_1_, p_74875_3_, 1, 1, 1, 3, 9, 3);
			
			// 占有範囲(structureboundingbox)内の指定範囲を置き換える
			// 占有範囲内の指定範囲は占有範囲原点を基準として(0,1,2), (0,2,2), (0,3,2)の位置を空気ブロックに置き換えている
			// 入り口っぽく壁に穴を空けている。coordBaseModeでランダムな方向になってることを確認できるようにするためです
			this.placeBlockAtCurrentPosition(p_74875_1_, Blocks.air, 0, 0, 1, 2, p_74875_3_);
			this.placeBlockAtCurrentPosition(p_74875_1_, Blocks.air, 0, 0, 2, 2, p_74875_3_);
			this.placeBlockAtCurrentPosition(p_74875_1_, Blocks.air, 0, 0, 3, 2, p_74875_3_);
			return true;
		}
	}
	
	
	public class ComponentTest2 extends StructureComponent{
		
		public  int color = 0;
		
		public ComponentTest2(){
			
		}
		
		public ComponentTest2(int par1, Random random, int par3, int par4, int par5){
			this.coordBaseMode = random.nextInt(4);
			switch(this.coordBaseMode) {
				case 0:
				case 1:
				case 2:
				case 3:
				default:
					// 占有範囲を設定(このサンプルではどの方角を向いてても同じ)
					// (x,y,z) = (par3, 64, par4)の地点から4x10x4ブロックが占有範囲
					this.boundingBox = new StructureBoundingBox(par3, 64, par4, par3 + 4, 74, par4 + 4);
					break;
			}
			this.color = par5;
		}
		
		@Override
		public void buildComponent(StructureComponent p_74861_1_, List p_74861_2_, Random p_74861_3_) {
			// 構成ブロックである羊毛の色を変えながらパーツをつなげる
			if(this.color < 15) {
				StructureComponent structureComponent1 = new ComponentTest2(0, p_74861_3_, this.boundingBox.maxX + 1, this.boundingBox.maxZ + 1, color + 1);
				((ComponentTest1)p_74861_1_).structureComponents.add(structureComponent1);
				p_74861_2_.add(structureComponent1);
			}
			else {
				// 羊毛の色を変えながらパーツをつなげて、最後の色まで到達したら終端のパーツをつなげる
				// 若干ランダムっぽさを演出するためパーツ3とパーツ4をランダムに選択
				if(p_74861_3_.nextBoolean()) {
					StructureComponent structureComponent = new ComponentTest3(0, p_74861_3_, this.boundingBox.minX, this.boundingBox.maxZ + 1);
					((ComponentTest1)p_74861_1_).structureComponents.add(structureComponent);
					p_74861_2_.add(structureComponent);
				}
				else {
					StructureComponent structureComponent = new ComponentTest4(0, p_74861_3_, this.boundingBox.maxX + 1, this.boundingBox.minZ);
					((ComponentTest1)p_74861_1_).structureComponents.add(structureComponent);
					p_74861_2_.add(structureComponent);
				}
			}
		}
		
		@Override
		protected void func_143012_a(NBTTagCompound p_143012_1_) {
			
		}
		
		@Override
		protected void func_143011_b(NBTTagCompound p_143011_1_) {
			
		}
		
		@Override
		public boolean addComponentParts(World p_74875_1_, Random p_74875_2_, StructureBoundingBox p_74875_3_) {
			if(this.isLiquidInStructureBoundingBox(p_74875_1_, p_74875_3_)) {
				return false;
			}
			
			// 指定の色の羊毛ブロックで範囲を埋める
			this.fillWithMetadataBlocks(p_74875_1_, p_74875_3_, 0, 0, 0, 4, 10, 4, Blocks.wool, this.color, Blocks.air, 0, false);
			
			this.fillWithAir(p_74875_1_, p_74875_3_, 1, 1, 1, 3, 9, 3);
			
			this.placeBlockAtCurrentPosition(p_74875_1_, Blocks.air, 0, 0, 1, 2, p_74875_3_);
			this.placeBlockAtCurrentPosition(p_74875_1_, Blocks.air, 0, 0, 2, 2, p_74875_3_);
			this.placeBlockAtCurrentPosition(p_74875_1_, Blocks.air, 0, 0, 3, 2, p_74875_3_);
			
			return true;
		}
	}
	
	
	public class ComponentTest3 extends StructureComponent {
		
		public ComponentTest3(){
			
		}
		
		public ComponentTest3(int par1, Random random, int par3, int par4){
			this.coordBaseMode = random.nextInt(4);
			switch(this.coordBaseMode) {
				case 0:
				case 1:
				case 2:
				case 3:
				default:
					// 占有範囲を設定(このサンプルではどの方角を向いてても同じ)
					// (x,y,z) = (par3, 64, par4)の地点から4x10x4ブロックが占有範囲
					this.boundingBox = new StructureBoundingBox(par3, 64, par4, par3 + 4, 74, par4 + 4);
					break;
			}
		}
		
		@Override
		protected void func_143012_a(NBTTagCompound p_143012_1_) {
			
		}
		
		@Override
		protected void func_143011_b(NBTTagCompound p_143011_1_) {
			
		}
		
		@Override
		public void buildComponent(StructureComponent p_74861_1_, List p_74861_2_, Random p_74861_3_) {
		}
		
		@Override
		public boolean addComponentParts(World p_74875_1_, Random p_74875_2_, StructureBoundingBox p_74875_3_) {
			if(this.isLiquidInStructureBoundingBox(p_74875_1_, p_74875_3_)) {
				return false;
			}
			
			// 鉄ブロックで範囲を埋める
			this.fillWithMetadataBlocks(p_74875_1_, p_74875_3_, 0, 0, 0, 4, 10, 4, Blocks.iron_block, 0, Blocks.air, 0, false);
			
			this.fillWithAir(p_74875_1_, p_74875_3_, 1, 1, 1, 3, 9, 3);
			
			this.placeBlockAtCurrentPosition(p_74875_1_, Blocks.air, 0, 0, 1, 2, p_74875_3_);
			this.placeBlockAtCurrentPosition(p_74875_1_, Blocks.air, 0, 0, 2, 2, p_74875_3_);
			this.placeBlockAtCurrentPosition(p_74875_1_, Blocks.air, 0, 0, 3, 2, p_74875_3_);
			
			return true;
		}
	}
	
	public class ComponentTest4 extends StructureComponent {
		
		public ComponentTest4(){
			
		}
		
		public ComponentTest4(int par1, Random random, int par3, int par4){
			this.coordBaseMode = random.nextInt(4);
			switch(this.coordBaseMode) {
				case 0:
				case 1:
				case 2:
				case 3:
				default:
					// 占有範囲を設定(このサンプルではどの方角を向いてても同じ)
					// (x,y,z) = (par3, 64, par4)の地点から4x10x4ブロックが占有範囲
					this.boundingBox = new StructureBoundingBox(par3, 64, par4, par3 + 4, 74, par4 + 4);
					break;
			}
		}
		
		@Override
		protected void func_143012_a(NBTTagCompound p_143012_1_) {
			
		}
		
		@Override
		protected void func_143011_b(NBTTagCompound p_143011_1_) {
			
		}
		
		@Override
		public void buildComponent(StructureComponent p_74861_1_, List p_74861_2_, Random p_74861_3_) {
		}
		
		@Override
		public boolean addComponentParts(World p_74875_1_, Random p_74875_2_, StructureBoundingBox p_74875_3_) {
			if(this.isLiquidInStructureBoundingBox(p_74875_1_, p_74875_3_)) {
			return false;
		}
			
			// ダイヤブロックで範囲を埋める
			this.fillWithMetadataBlocks(p_74875_1_, p_74875_3_, 0, 0, 0, 4, 10, 4, Blocks.diamond_block, 0, Blocks.air, 0, false);
			
			this.fillWithAir(p_74875_1_, p_74875_3_, 1, 1, 1, 3, 9, 3);
			
			this.placeBlockAtCurrentPosition(p_74875_1_, Blocks.air, 0, 0, 1, 2, p_74875_3_);
			this.placeBlockAtCurrentPosition(p_74875_1_, Blocks.air, 0, 0, 2, 2, p_74875_3_);
			this.placeBlockAtCurrentPosition(p_74875_1_, Blocks.air, 0, 0, 3, 2, p_74875_3_);
			
			return true;
		}
	}
	
} public class ComponentTiamatCenter extends StructureComponent {
	
	@SuppressWarnings("unused")
	public int radius = 5;
	
	List<StructureComponent> structureComponents = new ArrayList<>();
	
	@SuppressWarnings("unused")
	public ComponentTiamatCenter() {
	}
	
	@SuppressWarnings("unused")
	ComponentTiamatCenter(Random random, int chunkX, int chunkZ) {
		
		this.boundingBox = new StructureBoundingBox(chunkX << 4, 1, chunkZ << 4, 15, 150, 15);
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public void buildComponent(StructureComponent component, List list, Random random) {
		ComponentTiamatCenterLine componentE = new ComponentTiamatCenterLine(random, (this.boundingBox.minX >> 4) + 1, (this.boundingBox.minZ >> 4), ForgeDirection.EAST, 1);
		((ComponentTiamatCenter) component).structureComponents.add(componentE);
		list.add(componentE);
		ComponentTiamatCenterLine componentW = new ComponentTiamatCenterLine(random, (this.boundingBox.minX >> 4) - 1, (this.boundingBox.minZ >> 4), ForgeDirection.WEST, 1);
		((ComponentTiamatCenter) component).structureComponents.add(componentW);
		list.add(componentW);
		ComponentTiamatCenterLine componentS = new ComponentTiamatCenterLine(random, (this.boundingBox.minX >> 4), (this.boundingBox.minZ >> 4) + 1, ForgeDirection.SOUTH, 1);
		((ComponentTiamatCenter) component).structureComponents.add(componentS);
		list.add(componentS);
		ComponentTiamatCenterLine componentN = new ComponentTiamatCenterLine(random, (this.boundingBox.minX >> 4), (this.boundingBox.minZ >> 4) - 1, ForgeDirection.NORTH, 1);
		((ComponentTiamatCenter) component).structureComponents.add(componentN);
		list.add(componentN);
	}
	
	@Override
	protected void func_143012_a(NBTTagCompound p_143012_1_) {
		
	}
	
	@Override
	protected void func_143011_b(NBTTagCompound p_143011_1_) {
		
	}
	
	@Override
	public boolean addComponentParts(World world, Random random, StructureBoundingBox boundingBox) {
		this.fillWithAir(world, boundingBox, 0, 0, 0, 15, 150, 15);
		world.setBlock(0, 0, 0, AntiMatterModRegistry.explosionTestBlock);
		
		int X = 0, Y = 2 << 4, Z = 0, R = 5 << 4;
		
		Y:for (int y = Y - R; y <= Y; y++) {
			for (int x = X - R; x <= X + R; x++) {
				for (int z = Z - R; z <= Z + R; z++) {
					if (y <= 0) break Y;
					double dis = ((X - x) * (X - x) + ((Z - z) * (Z - z)) + ((Y - y) * (Y - y)));
					
					if (dis < R * R && y > 0) {
						world.setBlock(x, y, z, Blocks.air, 0, 2);
					}
				}
			}
		}
		return true;
	}
	
} public class ComponentTiamatCenterLine extends StructureComponent {
	
	private int count;
	
	private ForgeDirection direction;
	
	@SuppressWarnings("unused")
	public ComponentTiamatCenterLine(){}
	
	public ComponentTiamatCenterLine(Random random, int chunkX, int chunkZ, ForgeDirection direction, int count){
		this.count = count;
		this.boundingBox = new StructureBoundingBox(chunkX << 4, 1, chunkZ << 4, (chunkX << 4)+15,150,(chunkZ << 4)+15);
		this.direction = direction;
	}
	
	@Override
	public void buildComponent(StructureComponent p_74861_1_, List p_74861_2_, Random p_74861_3_) {
		
	}
	
	@Override
	protected void func_143012_a(NBTTagCompound p_143012_1_) {
		
	}
	
	@Override
	protected void func_143011_b(NBTTagCompound p_143011_1_) {
		
	}
	
	@Override
	public boolean addComponentParts(World world, Random random, StructureBoundingBox boundingBox) {
		this.fillWithAir(world,boundingBox, 0, 0, 0, 15, 150, 15);
		return true;
	}
} @SuppressWarnings({"unused", "FieldCanBeLocal"})
public class StructureTiamatStart extends StructureStart{
	
	private int centerChunkX, centerChunkZ;
	
	@SuppressWarnings("unused")
	public StructureTiamatStart(){}
	
	@SuppressWarnings("unchecked")
	StructureTiamatStart(World world, Random random, int chunkX, int chunkZ){
		this.centerChunkX = chunkX;
		this.centerChunkZ = chunkZ;
		ComponentTiamatCenter componentCenter = new ComponentTiamatCenter(random,chunkX,chunkZ);
		this.components.add(componentCenter);
		
		componentCenter.buildComponent(componentCenter,this.components,random);
		
		List<StructureComponent> list = componentCenter.structureComponents;
		while (!list.isEmpty()){
			int k = random.nextInt(list.size());
			StructureComponent structureComponent = list.remove(k);
			structureComponent.buildComponent(componentCenter,this.components,random);
		}
		
		this.updateBoundingBox();
	}
	
} public class ExplosionTestBlock extends Block {
	
	public ExplosionTestBlock() {
		super(Material.wood);
		this.setBlockName("ExplosionTestBlock");
	}
	
	@Override
	@SideOnly(Side.CLIENT)
	public IIcon getIcon(int side, int meta) {
		return Blocks.tnt.getIcon(side, meta);
	}
	
	@Override
	public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int px, float py, float pz, float f) {
		AMMExplosion explosion = new AMMExplosion(world, player, x, y, z, 10, 100);
		explosion.isFlaming = false;
		explosion.isSmoking = true;
		if (net.minecraftforge.event.ForgeEventFactory.onExplosionStart(world, explosion)) return true;
		explosion.doExplosionA();
		explosion.doExplosionB(false);
		return true;
	}
} @SidedProxy(clientSide = "antimattermod.core.client.ClientAntiMatterModCoreProxy", serverSide = "antimattermod.core.common.AntiMatterModCoreProxy")
public static AntiMatterModCoreProxy proxy;
import antimattermod.core.Block.BlockSoil;
import antimattermod.core.Block.ClayCrucible;
import antimattermod.core.Block.ClayCrucibleHeater;
import antimattermod.core.Block.TileEntity.TileEntityClayCrucible;
import antimattermod.core.Block.BlockSatStove;
import antimattermod.core.Block.Ores.BedrockOreBlock;
import antimattermod.core.Block.TileEntity.TileEntityClayCrucibleHeater;
import antimattermod.core.Item.ClayCruciblePattern;
import antimattermod.core.Item.ItemBlock.MetaItemBlock;
import antimattermod.core.Block.Ores.DifferentOreBlock;
import antimattermod.core.Block.Ores.OreBlock;
import antimattermod.core.Item.Marmite;
import antimattermod.core.Item.tool.*;
import antimattermod.core.Mob.EntityHoeHoeMan;
import antimattermod.core.Mob.ItemEgg.ItemHoeHoeManEgg;
import antimattermod.core.Mob.render.RenderHoeHoeMan;
import antimattermod.core.Util.AMMToolMaterial;
import antimattermod.core.Util.AddInformationfunction;
import antimattermod.core.Util.BlockUtil;
import antimattermod.core.Util.ItemUtil;
import antimattermod.core.World.Ore.OreGenerator;
import antimattermod.core.World.Structure.AMMStructureEventHandler;
import antimattermod.core.World.Structure.Test.StructureTestStart;
import antimattermod.core.World.Structure.Tiamat.ComponentTiamatCenter;
import antimattermod.core.World.Structure.Tiamat.ComponentTiamatCenterLine;
import antimattermod.core.World.Structure.Tiamat.StructureTiamatStart;
import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.registry.EntityRegistry;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemFood;
import net.minecraft.util.WeightedRandomChestContent;
import net.minecraft.world.gen.structure.MapGenStructureIO;
import net.minecraftforge.common.ChestGenHooks;
import net.minecraftforge.common.MinecraftForge;
import test.ExplosionTestBlock;
import static antimattermod.core.AntiMatterModCore.proxy;
package antimattermod.core;



/**
 * AMMのメインレジストリークラス
 *
 * @author C6H2Cl2
 */
@SuppressWarnings("WeakerAccess")
public class AntiMatterModRegistry {
	
	//CreativeTab ======================================================================================================
	//鉱石
	public static final CreativeTabs tabOreBlock = new CreativeTabs("amOreBlock") {
		@Override
		public Item getTabIconItem() {
			return Item.getItemFromBlock(Blocks.diamond_ore);
		}
	};
	//素材
	public final static CreativeTabs tabMaterials = new CreativeTabs("ammaterials") {
		@Override
		@SideOnly(Side.CLIENT)
		public Item getTabIconItem() {
			return ingot_01;
		}
	};
	//中間素材
	public final static CreativeTabs tabImaterial = new CreativeTabs("amIntermediateMaterial") {
		@Override
		public Item getTabIconItem() {
			return Items.iron_ingot;
		}
	};
	//機械・発電機
	public final static CreativeTabs tabMachines = new CreativeTabs("ammachines") {
		@Override
		public Item getTabIconItem() {
			return Item.getItemFromBlock(AMMRegistry.INSTANCE.getFurnaceGenerator());
		}
	};
	//ツール
	public final static CreativeTabs tabTools = new CreativeTabs("amtools") {
		@Override
		public Item getTabIconItem() {
			return hammer_01;
		}
	};
	//圧縮ブロック
	public final static CreativeTabs tabCompressedBlocks = new CreativeTabs("amcompressedblocks") {
		@Override
		public Item getTabIconItem() {
			return Item.getItemFromBlock(Blocks.iron_block);
		}
	};


	//==================================================================================================================
	
	//Item  ============================================================================================================
	//素材
	public static final Item crystal_01 = ItemUtil.CreateItem("crystal_01", "crystal/crystal_01", 6, AntiMatterModRegistry.tabMaterials);
	public static final Item crystal_02 = ItemUtil.CreateItem("crystal_02", "crystal/crystal_02", 1, AntiMatterModRegistry.tabMaterials);
	public static final Item powder_01 = ItemUtil.CreateItem("powder_01", "powder/powder_01", 1, AntiMatterModRegistry.tabMaterials);




	public static final Item ingot_01 = ItemUtil.CreateItem("ingot_01", "ingot/ingot_01", 11, AntiMatterModRegistry.tabMaterials, AddInformationfunction::IngotInformation);
	public static final Item nugget_01 = ItemUtil.CreateItem("nugget_01", "nugget/nugget_01", 10, AntiMatterModRegistry.tabMaterials);

	public static final Item authorIngot = ItemUtil.CreateItem("authorIngot", "author/ingot", 6, tabMaterials, AddInformationfunction::authorIngotInfo);
	public static final Item authorNugget = ItemUtil.CreateItem("authorNugget", "author/nugget", 6, AntiMatterModRegistry.tabMaterials);


	public static final Item alloyingot_01 = ItemUtil.CreateItem("alloyingot_01", "ingot/alloyingot_01", 17, AntiMatterModRegistry.tabMaterials);
	/*

	//合金

	//中間素材
	public static final Item wire_01 = ItemUtil.CreateItem("wire_01", "wire/wire_01", 1, AntiMatterModRegistry.tabImaterial);
	public static final Item plate_01 = ItemUtil.CreateItem("plate_01", "plate/plate_01", 8, AntiMatterModRegistry.tabImaterial);
	public static final Item crystalplate_02 = ItemUtil.CreateItem("crystalplate_02", "plate/crystalplate_02", 1, AntiMatterModRegistry.tabImaterial);
	public static final Item industrialplate_01 = ItemUtil.CreateItem("industrialplate_01", "plate/industrialplate_01", 1, AntiMatterModRegistry.tabImaterial);
	public static final Item conductivematerial_01 = ItemUtil.CreateItem("conductivematerial_01", "conductivematerial/conductivematerial_01", 1, AntiMatterModRegistry.tabImaterial);
	public static final Item stick_01 = ItemUtil.CreateItem("stick_01", "stick/stick_01", 1, AntiMatterModRegistry.tabImaterial);
	public static final Item industrialstick_01 = ItemUtil.CreateItem("industrialstick_01", "stick/industrialstick_01", 1, AntiMatterModRegistry.tabImaterial);
	public static final Item gear_01 = ItemUtil.CreateItem("gear_01", "gear/gear_01", 1, AntiMatterModRegistry.tabImaterial);
	public static final Item turbine_01 = ItemUtil.CreateItem("turbine_01", "turbine/turbine_01", 1, AntiMatterModRegistry.tabImaterial);
	public static final Item turbineblade_01 = ItemUtil.CreateItem("turbineblade_01", "turbine/turbineblade_01", 1, AntiMatterModRegistry.tabImaterial);
	public static final Item shaft_01 = ItemUtil.CreateItem("shaft_01", "turbine/shaft_01", 1, AntiMatterModRegistry.tabImaterial);
	public static final Item motor_01 = ItemUtil.CreateItem("motor_01", "motor/motor_01", 1, AntiMatterModRegistry.tabImaterial);
	public static final Item motorparts_01 = ItemUtil.CreateItem("motorparts_01", "motor/motorparts_01", 2, AntiMatterModRegistry.tabImaterial);
	public static final Item motormagnet_01 = ItemUtil.CreateItem("motormagnet_01", "motormagnet/motormagnet_01", 1, AntiMatterModRegistry.tabImaterial);
	public static final Item magnetizedingot_01 = ItemUtil.CreateItem("magnetizedingot_01", "motormagnet/magnetizedingot_01", 1, AntiMatterModRegistry.tabImaterial);
	public static final Item screw_01 = ItemUtil.CreateItem("screw_01", "screw/screw_01", 1, AntiMatterModRegistry.tabImaterial);

	*/
	//ツール中間素材
	public static final Item iron_tool_material = ItemUtil.CreateItem("iron_tool_material", "iron_tool_material", 5, AntiMatterModRegistry.tabImaterial);

	//粘土るつぼのパターンアイテム
	public static final Item clayCruciblePattern = new ClayCruciblePattern();

	//食料
	public static final ItemFood marmite = new Marmite("marmite");//マーマイト（エンドコンテンツ）

	//mobエッグ
	public static final Item itemEggHoeHoeMan = new ItemHoeHoeManEgg();//チュウボスの卵

	//ツール類
	public static final Item hammer_01 = new Hammer("IronHammer", "iron_hammer", AMMToolMaterial.IRON);//耐久値10のハンマーを追加(使えるのは11回)
	public static final Item wrench_01 = new Wrench("IronWrench", "iron_wrench", AMMToolMaterial.IRON);//耐久値10のレンチを追加(使えるのは11回)
	public static final Item wirecutter_01 = new WireCutter("IronWirecutter", "iron_wirecutter", AMMToolMaterial.IRON);//耐久値10のワイヤーカッターを追加(使えるのは11回)
	public static final Item file_01 = new File("IronFile", "iron_file", AMMToolMaterial.IRON);//耐久値10の鑢（ヤスリ）を追加(使えるのは11回)
	public static final Item screwdriver_01 = new ScrewDriver("IronScrewDriver", "iron_screwdriver", AMMToolMaterial.IRON);//耐久値10のドライバーを追加(使えるのは11回)

	//マイニングハンマー
	public static final Item miningHammer_01 = new MiningHammer("IronMiningHammer", "iron_mininghammer", AMMToolMaterial.IRON, 1);//鉄素材のハンマー3×3を追加
	public static final Item miningHammer_02 = new MiningHammer("DiamondMiningHammer", "diamond_mininghammer", AMMToolMaterial.DIAMOND, 1);//ダイヤ素材のハンマー3×3
	//==================================================================================================================

	//Block  ===========================================================================================================
	//鉱石
	public static final Block crystalOreBlock_1 = new DifferentOreBlock(Material.rock, "crystalOreBlock_01", "crystalore/crystaloreblock_01", AntiMatterModRegistry.tabOreBlock, 6, new float[]{5.0F, 5.0F, 5.0F, 5.0F, 5.0F, 5.0F}, new byte[]{3, 3, 3, 3, 3, 3}, crystal_01, new int[]{0, 1, 2, 3, 4, 5});
	public static final Block bedrockCrystalOreBlock_1 = new BedrockOreBlock("bedrockCrystalOreBlock_01", crystalOreBlock_1);
	public static final Block crystalOreBlock_2 = new DifferentOreBlock(Material.rock, "crystalOreBlock_02", "crystalore/crystaloreblock_02", AntiMatterModRegistry.tabOreBlock, 1, new float[]{5.0F}, new byte[]{3}, crystal_02, new int[]{0});
	public static final Block bedrockCrystalOreBlock_2 = new BedrockOreBlock("bedrockCrystalOreBlock_02", crystalOreBlock_2);
	public static final Block powderOreBlock_1 = new DifferentOreBlock(Material.rock, "powderOreBlock_01", "powderore/powderoreblock_01", AntiMatterModRegistry.tabOreBlock, 1, new float[]{5.0F}, new byte[]{3}, powder_01, new int[]{0}, new int[]{3, 3});
	public static final Block bedrockPowderOreBlock_1 = new BedrockOreBlock("bedrockPowderOreBlock_01", powderOreBlock_1);
	public static final Block oreBlock_1 = new OreBlock(Material.rock, "oreBlock_01", "ore/oreblock_01", AntiMatterModRegistry.tabOreBlock, 11, new float[]{5.0F, 5.0F, 5.0F, 5.0F, 5.0F, 5.0F, 5.0F, 5.0F, 5.0F, 5.0F, 5.0F}, new byte[]{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3});
	public static final Block bedrockOreBlock_1 = new BedrockOreBlock("bedrockOreBlock_01", oreBlock_1);

	//かまど
	public static final Block satStove = new BlockSatStove();

	//その他
	public static final Block soilBlock = new BlockSoil();

	//筐体
	public static final Block machinecasing = BlockUtil.CreateBlock("machinecasing", "casing/machinecasing_01", Material.rock, AntiMatterModRegistry.tabMachines, 2, 5f, 5f);
	public static final Block machinehull = BlockUtil.CreateBlock("machinehull", "casing/machinehull_01", Material.rock, AntiMatterModRegistry.tabMachines, 2, 5f, 5f);


	//インゴット系圧縮ブロック
	public static final Block tiamiteblock = BlockUtil.CreateBlock("tiamiteblock", "compressedblock/tiamiteblock", Material.rock, AntiMatterModRegistry.tabCompressedBlocks, 1, 5f, 5f);
	public static final Block ingotblock_01 = BlockUtil.CreateBlock("ingotblock_01", "compressedblock/ingotblock_01", Material.rock, AntiMatterModRegistry.tabCompressedBlocks, 16, 5f, 5f);
	public static final Block crystalblock_01 = BlockUtil.CreateBlock("crystalblock_01", "compressedblock/crystalblock_01", Material.rock, AntiMatterModRegistry.tabCompressedBlocks, 6, 5f, 5f);
	public static final Block crystalblock_02 = BlockUtil.CreateBlock("crystalblock_02", "compressedblock/crystalblock_02", Material.rock, AntiMatterModRegistry.tabCompressedBlocks, 1, 5f, 5f);
	public static final Block powderblock_01 = BlockUtil.CreateBlock("powderblock_01", "compressedblock/powderblock_01", Material.rock, AntiMatterModRegistry.tabCompressedBlocks, 1, 5f, 5f);

	//粘土るつぼ
	public static final Block clayCrucible = new ClayCrucible();
	public static final Block clayCrucibleHeater = new ClayCrucibleHeater();

	//テスト
	public static final Block explosionTestBlock = new ExplosionTestBlock();

	//==================================================================================================================


	//preinitで行う登録処理
	static void registerPreInit(@SuppressWarnings("UnusedParameters") FMLPreInitializationEvent event) {
		//Itemの登録 ===================================================================================================
		//素材
		GameRegistry.registerItem(ingot_01, "ingot_01");
		GameRegistry.registerItem(nugget_01, "nugget_01");
		GameRegistry.registerItem(authorIngot, "authorIngot");
		GameRegistry.registerItem(authorNugget, "authorNugget");
		GameRegistry.registerItem(crystal_01, "crystal_01");
		GameRegistry.registerItem(crystal_02, "crystal_02");
		GameRegistry.registerItem(powder_01, "powder_01");

		//ツール中間素材
		GameRegistry.registerItem(iron_tool_material, "iron_tool_material");
		//粘土るつぼのパターンアイテム
		GameRegistry.registerItem(clayCruciblePattern, "clayCruciblePattern");
		//食料
		GameRegistry.registerItem(marmite, "marmite");
		//モブEgg
		GameRegistry.registerItem(itemEggHoeHoeMan, "itemEggHoeHoeMan");
		//ツール
		GameRegistry.registerItem(hammer_01, "hammer_01");//追加
		GameRegistry.registerItem(wrench_01, "wrench_01");
		GameRegistry.registerItem(wirecutter_01, "wirecutter_01");
		GameRegistry.registerItem(file_01, "file_01");
		GameRegistry.registerItem(screwdriver_01, "screwdriver_01");

		//マイニングハンマー
		GameRegistry.registerItem(miningHammer_01, "miningHammer_01");
		GameRegistry.registerItem(miningHammer_02, "miningHammer_02");

		//Blockの登録 ==================================================================================================
		//鉱石
		GameRegistry.registerBlock(crystalOreBlock_1, MetaItemBlock.class, "crystalOreBlock_01");
		GameRegistry.registerBlock(crystalOreBlock_2, MetaItemBlock.class, "crystalOreBlock_02");
		GameRegistry.registerBlock(powderOreBlock_1, MetaItemBlock.class, "powderOreBlock_01");
		GameRegistry.registerBlock(oreBlock_1, MetaItemBlock.class, "oreBlock_01");
		//岩盤鉱石
		GameRegistry.registerBlock(bedrockCrystalOreBlock_1, MetaItemBlock.class, "bedrockCrystalOreBlock_01");
		GameRegistry.registerBlock(bedrockCrystalOreBlock_2, MetaItemBlock.class, "bedrockCrystalOreBlock_02");
		GameRegistry.registerBlock(bedrockPowderOreBlock_1, MetaItemBlock.class, "bedrockPowderOreBlock_01");
		GameRegistry.registerBlock(bedrockOreBlock_1, MetaItemBlock.class, "bedrockOreBlock_01");
		//機械
		GameRegistry.registerBlock(satStove, "satStove");
		GameRegistry.registerBlock(machinecasing, MetaItemBlock.class, "machinecasing");
		GameRegistry.registerBlock(machinehull, MetaItemBlock.class, "machinehull");
		//その他
		GameRegistry.registerBlock(soilBlock, "soilBlock");
		//鉱石ブロック
		GameRegistry.registerBlock(tiamiteblock, MetaItemBlock.class, "tiamiteblock");
		GameRegistry.registerBlock(ingotblock_01, MetaItemBlock.class, "ingotblock_01");
		GameRegistry.registerBlock(crystalblock_01, MetaItemBlock.class, "crystalblock_01");
		GameRegistry.registerBlock(crystalblock_02, MetaItemBlock.class, "crystalblock_02");
		GameRegistry.registerBlock(powderblock_01, MetaItemBlock.class, "powderblock_01");
		//粘土るつぼ
		GameRegistry.registerBlock(clayCrucible, "clayCrucible");
		GameRegistry.registerBlock(clayCrucibleHeater, "clayCrucibleHeater");

		//テスト
		GameRegistry.registerBlock(explosionTestBlock, "explosionTestBlock");

		//Renderの登録 =================================================================================================
		proxy.registerRenderThings();