• Recently Browsing

    No registered users viewing this page.

  • Posts

    • package net.minecraft.block; import java.util.Random; import javax.annotation.Nullable; 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.creativetab.CreativeTabs; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.stats.StatList; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.IStringSerializable; import net.minecraft.util.NonNullList; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; public class BlockDoublePlant extends BlockBush implements IGrowable, net.minecraftforge.common.IShearable { public static final PropertyEnum<BlockDoublePlant.EnumPlantType> VARIANT = PropertyEnum.<BlockDoublePlant.EnumPlantType>create("variant", BlockDoublePlant.EnumPlantType.class); public static final PropertyEnum<BlockDoublePlant.EnumBlockHalf> HALF = PropertyEnum.<BlockDoublePlant.EnumBlockHalf>create("half", BlockDoublePlant.EnumBlockHalf.class); public static final PropertyEnum<EnumFacing> FACING = BlockHorizontal.FACING; public BlockDoublePlant() { super(Material.VINE); this.setDefaultState(this.blockState.getBaseState().withProperty(VARIANT, BlockDoublePlant.EnumPlantType.SUNFLOWER).withProperty(HALF, BlockDoublePlant.EnumBlockHalf.LOWER).withProperty(FACING, EnumFacing.NORTH)); this.setHardness(0.0F); this.setSoundType(SoundType.PLANT); this.setUnlocalizedName("doublePlant"); } public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) { return FULL_BLOCK_AABB; } private BlockDoublePlant.EnumPlantType getType(IBlockAccess blockAccess, BlockPos pos, IBlockState state) { if (state.getBlock() == this) { state = state.getActualState(blockAccess, pos); return (BlockDoublePlant.EnumPlantType)state.getValue(VARIANT); } else { return BlockDoublePlant.EnumPlantType.FERN; } } /** * Checks if this block can be placed exactly at the given position. */ public boolean canPlaceBlockAt(World worldIn, BlockPos pos) { return super.canPlaceBlockAt(worldIn, pos) && worldIn.isAirBlock(pos.up()); } /** * Whether this Block can be replaced directly by other blocks (true for e.g. tall grass) */ public boolean isReplaceable(IBlockAccess worldIn, BlockPos pos) { IBlockState iblockstate = worldIn.getBlockState(pos); if (iblockstate.getBlock() != this) { return true; } else { BlockDoublePlant.EnumPlantType blockdoubleplant$enumplanttype = (BlockDoublePlant.EnumPlantType)iblockstate.getActualState(worldIn, pos).getValue(VARIANT); return blockdoubleplant$enumplanttype == BlockDoublePlant.EnumPlantType.FERN || blockdoubleplant$enumplanttype == BlockDoublePlant.EnumPlantType.GRASS; } } protected void checkAndDropBlock(World worldIn, BlockPos pos, IBlockState state) { if (!this.canBlockStay(worldIn, pos, state)) { boolean flag = state.getValue(HALF) == BlockDoublePlant.EnumBlockHalf.UPPER; BlockPos blockpos = flag ? pos : pos.up(); BlockPos blockpos1 = flag ? pos.down() : pos; Block block = (Block)(flag ? this : worldIn.getBlockState(blockpos).getBlock()); Block block1 = (Block)(flag ? worldIn.getBlockState(blockpos1).getBlock() : this); if (!flag) this.dropBlockAsItem(worldIn, pos, state, 0); //Forge move above the setting to air. if (block == this) { worldIn.setBlockState(blockpos, Blocks.AIR.getDefaultState(), 2); } if (block1 == this) { worldIn.setBlockState(blockpos1, Blocks.AIR.getDefaultState(), 3); } } } public boolean canBlockStay(World worldIn, BlockPos pos, IBlockState state) { if (state.getBlock() != this) return super.canBlockStay(worldIn, pos, state); //Forge: This function is called during world gen and placement, before this block is set, so if we are not 'here' then assume it's the pre-check. if (state.getValue(HALF) == BlockDoublePlant.EnumBlockHalf.UPPER) { return worldIn.getBlockState(pos.down()).getBlock() == this; } else { IBlockState iblockstate = worldIn.getBlockState(pos.up()); return iblockstate.getBlock() == this && super.canBlockStay(worldIn, pos, iblockstate); } } /** * Get the Item that this Block should drop when harvested. */ public Item getItemDropped(IBlockState state, Random rand, int fortune) { if (state.getValue(HALF) == BlockDoublePlant.EnumBlockHalf.UPPER) { return Items.AIR; } else { BlockDoublePlant.EnumPlantType blockdoubleplant$enumplanttype = (BlockDoublePlant.EnumPlantType)state.getValue(VARIANT); if (blockdoubleplant$enumplanttype == BlockDoublePlant.EnumPlantType.FERN) { return Items.AIR; } else if (blockdoubleplant$enumplanttype == BlockDoublePlant.EnumPlantType.GRASS) { return rand.nextInt(8) == 0 ? Items.WHEAT_SEEDS : Items.AIR; } else { return super.getItemDropped(state, rand, fortune); } } } /** * Gets the metadata of the item this Block can drop. This method is called when the block gets destroyed. It * returns the metadata of the dropped item based on the old metadata of the block. */ public int damageDropped(IBlockState state) { return state.getValue(HALF) != BlockDoublePlant.EnumBlockHalf.UPPER && state.getValue(VARIANT) != BlockDoublePlant.EnumPlantType.GRASS ? ((BlockDoublePlant.EnumPlantType)state.getValue(VARIANT)).getMeta() : 0; } public void placeAt(World worldIn, BlockPos lowerPos, BlockDoublePlant.EnumPlantType variant, int flags) { worldIn.setBlockState(lowerPos, this.getDefaultState().withProperty(HALF, BlockDoublePlant.EnumBlockHalf.LOWER).withProperty(VARIANT, variant), flags); worldIn.setBlockState(lowerPos.up(), this.getDefaultState().withProperty(HALF, BlockDoublePlant.EnumBlockHalf.UPPER), flags); } /** * Called by ItemBlocks after a block is set in the world, to allow post-place logic */ public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) { worldIn.setBlockState(pos.up(), this.getDefaultState().withProperty(HALF, BlockDoublePlant.EnumBlockHalf.UPPER), 2); } /** * Spawns the block's drops in the world. By the time this is called the Block has possibly been set to air via * Block.removedByPlayer */ public void harvestBlock(World worldIn, EntityPlayer player, BlockPos pos, IBlockState state, @Nullable TileEntity te, ItemStack stack) { { super.harvestBlock(worldIn, player, pos, state, te, stack); } } /** * Called before the Block is set to air in the world. Called regardless of if the player's tool can actually * collect this block */ public void onBlockHarvested(World worldIn, BlockPos pos, IBlockState state, EntityPlayer player) { if (state.getValue(HALF) == BlockDoublePlant.EnumBlockHalf.UPPER) { if (worldIn.getBlockState(pos.down()).getBlock() == this) { if (player.capabilities.isCreativeMode) { worldIn.setBlockToAir(pos.down()); } else { IBlockState iblockstate = worldIn.getBlockState(pos.down()); BlockDoublePlant.EnumPlantType blockdoubleplant$enumplanttype = (BlockDoublePlant.EnumPlantType)iblockstate.getValue(VARIANT); if (blockdoubleplant$enumplanttype != BlockDoublePlant.EnumPlantType.FERN && blockdoubleplant$enumplanttype != BlockDoublePlant.EnumPlantType.GRASS) { worldIn.destroyBlock(pos.down(), true); } else if (worldIn.isRemote) { worldIn.setBlockToAir(pos.down()); } else if (!player.getHeldItemMainhand().isEmpty() && player.getHeldItemMainhand().getItem() == Items.SHEARS) { this.onHarvest(worldIn, pos, iblockstate, player); worldIn.setBlockToAir(pos.down()); } else { worldIn.destroyBlock(pos.down(), true); } } } } else if (worldIn.getBlockState(pos.up()).getBlock() == this) { worldIn.setBlockState(pos.up(), Blocks.AIR.getDefaultState(), 2); } super.onBlockHarvested(worldIn, pos, state, player); } private boolean onHarvest(World worldIn, BlockPos pos, IBlockState state, EntityPlayer player) { BlockDoublePlant.EnumPlantType blockdoubleplant$enumplanttype = (BlockDoublePlant.EnumPlantType)state.getValue(VARIANT); if (blockdoubleplant$enumplanttype != BlockDoublePlant.EnumPlantType.FERN && blockdoubleplant$enumplanttype != BlockDoublePlant.EnumPlantType.GRASS) { return false; } else { player.addStat(StatList.getBlockStats(this)); return true; } } /** * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) */ public void getSubBlocks(CreativeTabs itemIn, NonNullList<ItemStack> items) { for (BlockDoublePlant.EnumPlantType blockdoubleplant$enumplanttype : BlockDoublePlant.EnumPlantType.values()) { items.add(new ItemStack(this, 1, blockdoubleplant$enumplanttype.getMeta())); } } public ItemStack getItem(World worldIn, BlockPos pos, IBlockState state) { return new ItemStack(this, 1, this.getType(worldIn, pos, state).getMeta()); } /** * Whether this IGrowable can grow */ public boolean canGrow(World worldIn, BlockPos pos, IBlockState state, boolean isClient) { BlockDoublePlant.EnumPlantType blockdoubleplant$enumplanttype = this.getType(worldIn, pos, state); return blockdoubleplant$enumplanttype != BlockDoublePlant.EnumPlantType.GRASS && blockdoubleplant$enumplanttype != BlockDoublePlant.EnumPlantType.FERN; } public boolean canUseBonemeal(World worldIn, Random rand, BlockPos pos, IBlockState state) { return true; } public void grow(World worldIn, Random rand, BlockPos pos, IBlockState state) { spawnAsEntity(worldIn, pos, new ItemStack(this, 1, this.getType(worldIn, pos, state).getMeta())); } /** * Convert the given metadata into a BlockState for this Block */ public IBlockState getStateFromMeta(int meta) { return (meta & 8) > 0 ? this.getDefaultState().withProperty(HALF, BlockDoublePlant.EnumBlockHalf.UPPER) : this.getDefaultState().withProperty(HALF, BlockDoublePlant.EnumBlockHalf.LOWER).withProperty(VARIANT, BlockDoublePlant.EnumPlantType.byMetadata(meta & 7)); } /** * Get the actual Block state of this Block at the given position. This applies properties not visible in the * metadata, such as fence connections. */ public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) { if (state.getValue(HALF) == BlockDoublePlant.EnumBlockHalf.UPPER) { IBlockState iblockstate = worldIn.getBlockState(pos.down()); if (iblockstate.getBlock() == this) { state = state.withProperty(VARIANT, iblockstate.getValue(VARIANT)); } } return state; } /** * Convert the BlockState into the correct metadata value */ public int getMetaFromState(IBlockState state) { return state.getValue(HALF) == BlockDoublePlant.EnumBlockHalf.UPPER ? 8 | ((EnumFacing)state.getValue(FACING)).getHorizontalIndex() : ((BlockDoublePlant.EnumPlantType)state.getValue(VARIANT)).getMeta(); } protected BlockStateContainer createBlockState() { return new BlockStateContainer(this, new IProperty[] {HALF, VARIANT, FACING}); } /** * Get the OffsetType for this Block. Determines if the model is rendered slightly offset. */ public Block.EnumOffsetType getOffsetType() { return Block.EnumOffsetType.XZ; } @Override public boolean isShearable(ItemStack item, IBlockAccess world, BlockPos pos) { IBlockState state = world.getBlockState(pos); EnumPlantType type = (EnumPlantType)state.getValue(VARIANT); return state.getValue(HALF) == EnumBlockHalf.LOWER && (type == EnumPlantType.FERN || type == EnumPlantType.GRASS); } @Override public java.util.List<ItemStack> onSheared(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) { java.util.List<ItemStack> ret = new java.util.ArrayList<ItemStack>(); EnumPlantType type = (EnumPlantType)world.getBlockState(pos).getValue(VARIANT); if (type == EnumPlantType.FERN) ret.add(new ItemStack(Blocks.TALLGRASS, 2, BlockTallGrass.EnumType.FERN.getMeta())); if (type == EnumPlantType.GRASS) ret.add(new ItemStack(Blocks.TALLGRASS, 2, BlockTallGrass.EnumType.GRASS.getMeta())); return ret; } public static enum EnumBlockHalf implements IStringSerializable { UPPER, LOWER; public String toString() { return this.getName(); } public String getName() { return this == UPPER ? "upper" : "lower"; } } public static enum EnumPlantType implements IStringSerializable { SUNFLOWER(0, "sunflower"), SYRINGA(1, "syringa"), GRASS(2, "double_grass", "grass"), FERN(3, "double_fern", "fern"), ROSE(4, "double_rose", "rose"), PAEONIA(5, "paeonia"); private static final BlockDoublePlant.EnumPlantType[] META_LOOKUP = new BlockDoublePlant.EnumPlantType[values().length]; private final int meta; private final String name; private final String unlocalizedName; private EnumPlantType(int meta, String name) { this(meta, name, name); } private EnumPlantType(int meta, String name, String unlocalizedName) { this.meta = meta; this.name = name; this.unlocalizedName = unlocalizedName; } public int getMeta() { return this.meta; } public String toString() { return this.name; } public static BlockDoublePlant.EnumPlantType byMetadata(int meta) { if (meta < 0 || meta >= META_LOOKUP.length) { meta = 0; } return META_LOOKUP[meta]; } public String getName() { return this.name; } public String getUnlocalizedName() { return this.unlocalizedName; } static { for (BlockDoublePlant.EnumPlantType blockdoubleplant$enumplanttype : values()) { META_LOOKUP[blockdoubleplant$enumplanttype.getMeta()] = blockdoubleplant$enumplanttype; } } } } Well, I can only find this.
    • I had the same issue. remove optifine from your mods directory and reload. worked for me.
    • You appear to be using a 1.14 version of Neat on 1.15.2, try removing it
    • Well... significant progress. I think the moral of the story here is that one should not try and do a Blender custom model unless they actually put the texture in first, and then align it using the steps I had in my previous post so that its correctly laid out. Seems the UV orientation is contained in the OBJ data. Unfortunately OBJ syntax feels more like machine code rather than meant-for-a-human-to-write-manually, so I couldn't begin to guess at the differences. It also appears, as can be seen in my screenshot below, that stairs are literally upside-down blocks, which is why the texture is likewise also upside-down, hence the lines in the oak planks texture not lining up. So it appears I'll need an additional model just for that variant, since the model determines the UV orientation, and that determines the orientation of the textures.   And my MTL file, fyi, is still just this simple, so it could point at any existing texture. I wanted to make sure I did it this way so that texture packs that replace vanilla textures would automatically apply here as well. # Blender MTL File: 'fortyfive.blend' # Material Count: 1 newmtl fortyfive map_Kd minecraft:block/oak_planks   Unfortunately unless I can figure out how to assign the actual texture image file to the model dynamically in the Java code, I think I'm going to abort much more work on this mod attempt. I wanted to introduce diagonal blocks of all applicable material types (stone, quartz, etc) but I haven't found any examples where this has been done. The model would stay the same, but the image used for the texture would be changed. I'm not excited about making several hundred JSON -> OBJ -> MTL file sets just to accomplish that. Seems like there should be a simpler way of using the same JSON -> OBJ file chain and assigning the MTL within Java instead of a static file.    
    • Ugh. Don't remind me. I've spent the better part of that six months not doing anything because of a hard dependency that I'm both unwilling to abandon and unable to get updated. Worldgen is complicated.
  • Topics

  • Who's Online (See full list)