package fr.jackcartersmith.orbsat.block; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import com.google.common.collect.Sets; import fr.jackcartersmith.orbsat.OSRefs; import fr.jackcartersmith.orbsat.OrbitalSatellite; import fr.jackcartersmith.orbsat.block.OSBlockInterface.IOSMetaBlock; import net.minecraft.block.Block; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; import net.minecraft.block.properties.PropertyEnum; import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.block.statemap.StateMapperBase; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; import net.minecraft.util.IStringSerializable; import net.minecraft.util.math.BlockPos; import net.minecraft.world.Explosion; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.common.property.ExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; public class BlockOSBase & BlockOSBase.IBlockEnum> extends Block implements IOSMetaBlock{ protected static IProperty[] tempProperties; protected static IUnlistedProperty[] tempUnlistedProperties; public final String name; public final PropertyEnum property; public final IProperty[] additionalProperties; public final IUnlistedProperty[] additionalUnlistedProperties; public final E[] enumValues; boolean[] isMetaHidden; boolean[] hasFlavour; protected Set renderLayers = Sets.newHashSet(BlockRenderLayer.SOLID); protected Set[] metaRenderLayers; protected Map metaLightOpacities = new HashMap<>(); protected Map metaResistances = new HashMap<>(); protected boolean[] metaNotNormalBlock; private boolean opaqueCube = false; public BlockOSBase(String name, Material material, PropertyEnum mainProperty, Class itemBlock, Object... additionalProperties) { super(setTempProperties(material, mainProperty, additionalProperties)); this.name = name; this.property = mainProperty; this.enumValues = mainProperty.getValueClass().getEnumConstants(); this.isMetaHidden = new boolean[this.enumValues.length]; this.hasFlavour = new boolean[this.enumValues.length]; this.metaRenderLayers = new Set[this.enumValues.length]; ArrayList propList = new ArrayList(); ArrayList unlistedPropList = new ArrayList(); for(Object o : additionalProperties) { if(o instanceof IProperty) propList.add((IProperty)o); if(o instanceof IProperty[]) for(IProperty p : ((IProperty[])o)) propList.add(p); if(o instanceof IUnlistedProperty) unlistedPropList.add((IUnlistedProperty)o); if(o instanceof IUnlistedProperty[]) for(IUnlistedProperty p : ((IUnlistedProperty[])o)) unlistedPropList.add(p); } this.additionalProperties = propList.toArray(new IProperty[propList.size()]); this.additionalUnlistedProperties = unlistedPropList.toArray(new IUnlistedProperty[unlistedPropList.size()]); this.setDefaultState(getInitDefaultState()); String registryName = createRegistryName(); this.setUnlocalizedName(registryName.replace(':', '.')); this.setCreativeTab(OrbitalSatellite.creativeTab); this.adjustSound(); OrbitalSatellite.registerBlockByFullName(this, itemBlock, registryName); OSRefs.registeredOSBlocks.add(this); lightOpacity = 255; } @Override public String getOSBlockName() { return this.name; } @Override public Enum[] getMetaEnums() { return enumValues; } @Override public IBlockState getInventoryState(int meta) { IBlockState state = this.blockState.getBaseState().withProperty(this.property, enumValues[meta]); // for(int i=0; i getMetaProperty() { return this.property; } @Override public boolean useCustomStateMapper() { return false; } @Override public String getCustomStateMapping(int meta, boolean itemBlock) { return null; } @Override @SideOnly(Side.CLIENT) public StateMapperBase getCustomMapper() { return null; } @Override public boolean appendPropertiesToState() { return true; } public String getUnlocalizedName(ItemStack stack) { String subName = getStateFromMeta(stack.getItemDamage()).getValue(property).toString().toLowerCase(Locale.US); return super.getUnlocalizedName() + "." + subName; } protected static Material setTempProperties(Material material, PropertyEnum property, Object... additionalProperties) { ArrayList propList = new ArrayList(); ArrayList unlistedPropList = new ArrayList(); propList.add(property); for(Object o : additionalProperties) { if(o instanceof IProperty) propList.add((IProperty)o); if(o instanceof IProperty[]) for(IProperty p : ((IProperty[])o)) propList.add(p); if(o instanceof IUnlistedProperty) unlistedPropList.add((IUnlistedProperty)o); if(o instanceof IUnlistedProperty[]) for(IUnlistedProperty p : ((IUnlistedProperty[])o)) unlistedPropList.add(p); } tempProperties = propList.toArray(new IProperty[propList.size()]); tempUnlistedProperties = unlistedPropList.toArray(new IUnlistedProperty[unlistedPropList.size()]); return material; } protected static Object[] combineProperties(Object[] currentProperties, Object... addedProperties) { Object[] array = new Object[currentProperties.length + addedProperties.length]; for(int i=0; i=0 && i=0 && i=0 && i setBlockLayer(BlockRenderLayer... layer) { this.renderLayers = Sets.newHashSet(layer); return this; } public BlockOSBase setMetaBlockLayer(int meta, BlockRenderLayer... layer) { this.metaRenderLayers[Math.max(0, Math.min(meta, this.metaRenderLayers.length-1))] = Sets.newHashSet(layer); return this; } @Override public boolean canRenderInLayer(BlockRenderLayer layer) { if(cachedTileRequestState!=null) { int meta = this.getMetaFromState(cachedTileRequestState); if(meta>=0 && meta setMetaLightOpacity(int meta, int opacity) { metaLightOpacities.put(meta, opacity); return this; } @Override public int getLightOpacity(IBlockState state, IBlockAccess w, BlockPos pos) { int meta = getMetaFromState(state); if(metaLightOpacities.containsKey(meta)) return metaLightOpacities.get(meta); return super.getLightOpacity(state,w,pos); } public BlockOSBase setMetaExplosionResistance(int meta, int resistance) { metaResistances.put(meta, resistance); return this; } @Override public float getExplosionResistance(World world, BlockPos pos, Entity exploder, Explosion explosion) { int meta = getMetaFromState(world.getBlockState(pos)); if(metaResistances.containsKey(meta)) return metaResistances.get(meta); return super.getExplosionResistance(world, pos, exploder, explosion); } public BlockOSBase setNotNormalBlock(int meta) { if(metaNotNormalBlock == null) metaNotNormalBlock = new boolean[this.enumValues.length]; metaNotNormalBlock[meta] = true; return this; } public BlockOSBase setAllNotNormalBlock() { if(metaNotNormalBlock == null) metaNotNormalBlock = new boolean[this.enumValues.length]; for(int i = 0; i < metaNotNormalBlock.length; i++) metaNotNormalBlock[i] = true; return this; } protected boolean normalBlockCheck(IBlockState state) { if(metaNotNormalBlock == null) return true; int meta = getMetaFromState(state); return (meta < 0 || meta >= metaNotNormalBlock.length) || !metaNotNormalBlock[meta]; } @Override public boolean isFullBlock(IBlockState state) { return normalBlockCheck(state); } @Override public boolean isFullCube(IBlockState state) { return normalBlockCheck(state); } @Override public boolean isOpaqueCube(IBlockState state) { return normalBlockCheck(state); } @Override public boolean isVisuallyOpaque() { if(metaNotNormalBlock == null) return true; int majority = 0; for(boolean b : metaNotNormalBlock) if(b) majority++; return majority0) return new ExtendedBlockState(this, array, additionalUnlistedProperties); return new BlockStateContainer(this, array); } protected IBlockState getInitDefaultState() { IBlockState state = this.blockState.getBaseState().withProperty(this.property, enumValues[0]); for(int i=0; i> IBlockState applyProperty(IBlockState in, IProperty prop, Object val) { return in.withProperty(prop, (V)val); } public void onIEBlockPlacedBy(World world, BlockPos pos, IBlockState state, EnumFacing side, float hitX, float hitY, float hitZ, EntityLivingBase placer, ItemStack stack) { } public boolean canIEBlockBePlaced(World world, BlockPos pos, IBlockState newState, EnumFacing side, float hitX, float hitY, float hitZ, EntityPlayer player, ItemStack stack) { return true; } @Override protected BlockStateContainer createBlockState() { if(this.property!=null) return createNotTempBlockState(); if(tempUnlistedProperties.length>0) return new ExtendedBlockState(this, tempProperties, tempUnlistedProperties); return new BlockStateContainer(this, tempProperties); } @Override public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) { super.onBlockPlacedBy(worldIn, pos, state, placer, stack); } @Override public int getMetaFromState(IBlockState state) { if(state==null || !this.equals(state.getBlock())) return 0; return state.getValue(this.property).getMeta(); } @Override public IBlockState getActualState(IBlockState state, IBlockAccess world, BlockPos pos) { for(int i=0; i=enumValues.length) meta = 0; return enumValues[meta]; } @Override public int damageDropped(IBlockState state) { return getMetaFromState(state); } @SideOnly(Side.CLIENT) @Override public void getSubBlocks(Item item, CreativeTabs tab, List list) { for(E type : this.enumValues) if(type.listForCreative() && !this.isMetaHidden[type.getMeta()]) list.add(new ItemStack(this, 1, type.getMeta())); } void adjustSound() { if(this.blockMaterial==Material.ANVIL) this.blockSoundType = SoundType.ANVIL; else if(this.blockMaterial==Material.CARPET||this.blockMaterial==Material.CLOTH) this.blockSoundType = SoundType.CLOTH; else if(this.blockMaterial==Material.GLASS||this.blockMaterial==Material.ICE) this.blockSoundType = SoundType.GLASS; else if(this.blockMaterial==Material.GRASS||this.blockMaterial==Material.TNT||this.blockMaterial==Material.PLANTS||this.blockMaterial==Material.VINE) this.blockSoundType = SoundType.PLANT; else if(this.blockMaterial==Material.GROUND) this.blockSoundType = SoundType.GROUND; else if(this.blockMaterial==Material.IRON) this.blockSoundType = SoundType.METAL; else if(this.blockMaterial==Material.SAND) this.blockSoundType = SoundType.SAND; else if(this.blockMaterial==Material.SNOW) this.blockSoundType = SoundType.SNOW; else if(this.blockMaterial==Material.ROCK) this.blockSoundType = SoundType.STONE; else if(this.blockMaterial==Material.WOOD||this.blockMaterial==Material.CACTUS) this.blockSoundType = SoundType.WOOD; } @Override public boolean eventReceived(IBlockState state, World worldIn, BlockPos pos, int eventID, int eventParam) { if (worldIn.isRemote&&eventID==255) { worldIn.notifyBlockUpdate(pos,state,state,3); return true; } return super.eventReceived(state, worldIn, pos, eventID, eventParam); } public boolean allowHammerHarvest(IBlockState blockState) { return false; } public boolean allowWirecutterHarvest(IBlockState blockState) { return false; } public boolean isOpaqueCube() { return opaqueCube; } public BlockOSBase setOpaque(boolean isOpaque) { opaqueCube = isOpaque; fullBlock = isOpaque; return this; } /* @Override public boolean isToolEffective(String type, IBlockState state) { if(allowHammerHarvest(state) && type.equals(Lib.TOOL_HAMMER)) return true; if(allowWirecutterHarvest(state) && type.equals(Lib.TOOL_WIRECUTTER)) return true; return super.isToolEffective(type, state); } */ public String createRegistryName() { return OSRefs.MODID+":"+name; } public interface IBlockEnum extends IStringSerializable { int getMeta(); boolean listForCreative(); } public abstract static class IELadderBlock & IBlockEnum> extends BlockOSBase { public IELadderBlock(String name, Material material, PropertyEnum mainProperty, Class itemBlock, Object... additionalProperties) { super(name, material, mainProperty, itemBlock, additionalProperties); } @Override public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, IBlockState state, Entity entityIn) { super.onEntityCollidedWithBlock(worldIn, pos, state, entityIn); if (entityIn instanceof EntityLivingBase&&!((EntityLivingBase) entityIn).isOnLadder()&&isLadder(state, worldIn, pos, (EntityLivingBase)entityIn)) { float f5 = 0.15F; if (entityIn.motionX < -f5) entityIn.motionX = -f5; if (entityIn.motionX > f5) entityIn.motionX = f5; if (entityIn.motionZ < -f5) entityIn.motionZ = -f5; if (entityIn.motionZ > f5) entityIn.motionZ = f5; entityIn.fallDistance = 0.0F; if (entityIn.motionY < -0.15D) entityIn.motionY = -0.15D; if(entityIn.motionY<0 && entityIn instanceof EntityPlayer && entityIn.isSneaking()) { entityIn.motionY=.05; return; } if(entityIn.isCollidedHorizontally) entityIn.motionY=.2; } } } }