So I have been working on teaching myself modding for the past few days in an attempt to put forth a concept I had.
Basically, it adds in a growth that spreads across blocks, with the goal to have it behave similar to the taint in Thaumcraft, with the idea being you can command this growth, similar to the Creep in Starcraft.
To that end, I have named this block Creep.
However, the textures for this block are not loading. Below is why.
Exception loading model for variant testenvironmentmod:creep#down=false,east=false,north=true,south=false,up=true,west=true for blockstate "testenvironmentmod:creep[down=false,east=false,north=true,south=false,up=true,west=true]"
I would appreciate help with understanding this. I think I need to define the textures in the script? But as I said, I am literally teaching myself how to do this, so I'm not sure. Below is the code for the Creep Block
package mod.mcreator;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.common.registry.ForgeRegistries;
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
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.PropertyBool;
import net.minecraft.block.state.BlockFaceShape;
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.BlockRenderLayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraft.item.ItemBlock;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.Minecraft;
import net.minecraft.block.SoundType;
import net.minecraft.block.Block;
import java.util.HashMap;
public class mcreator_creep {
public mcreator_creep() {
}
public static BlockCreep block;
public static Item item;
public static Object instance;
public int addFuel(ItemStack fuel) {
return 0;
}
public void serverLoad(FMLServerStartingEvent event) {
}
public void preInit(FMLPreInitializationEvent event) {
block.setRegistryName("creep");
ForgeRegistries.BLOCKS.register(block);
item = new ItemBlock(block).setRegistryName(block.getRegistryName());
ForgeRegistries.ITEMS.register(item);
}
public void registerRenderers() {
}
public void load(FMLInitializationEvent event) {
if (event.getSide() == Side.CLIENT) {
Minecraft.getMinecraft().getRenderItem().getItemModelMesher()
.register(item, 0, new ModelResourceLocation("testenvironmentmod:creep", "inventory"));
}
}
static {
block = (BlockCreep) (new BlockCreep().setHardness(2.0F).setResistance(10.0F).setLightLevel(0.0F).setUnlocalizedName("creep")
.setLightOpacity(0).setCreativeTab(mcreator_creepCraft.tab));
block.setHarvestLevel("axe", 4);
}
public void generateSurface(World world, Random random, int chunkX, int chunkZ) {
}
public void generateNether(World world, Random random, int chunkX, int chunkZ) {
}
static class BlockCreep extends Block {
public static final PropertyBool UP = PropertyBool.create("up");
public static final PropertyBool DOWN = PropertyBool.create("down");
public static final PropertyBool NORTH = PropertyBool.create("north");
public static final PropertyBool EAST = PropertyBool.create("east");
public static final PropertyBool SOUTH = PropertyBool.create("south");
public static final PropertyBool WEST = PropertyBool.create("west");
public static final PropertyBool[] ALL_FACES = new PropertyBool[] {UP, DOWN, NORTH, SOUTH, WEST, EAST};
protected static final AxisAlignedBB UP_AABB = new AxisAlignedBB(0.0D, 0.9375D, 0.0D, 1.0D, 1.0D, 1.0D);
protected static final AxisAlignedBB DOWN_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.0625D, 1.0D);
protected static final AxisAlignedBB WEST_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.0625D, 1.0D, 1.0D);
protected static final AxisAlignedBB EAST_AABB = new AxisAlignedBB(0.9375D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D);
protected static final AxisAlignedBB NORTH_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 0.0625D);
protected static final AxisAlignedBB SOUTH_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.9375D, 1.0D, 1.0D, 1.0D);
protected BlockCreep() {
super(Material.VINE);
this.setDefaultState(this.blockState.getBaseState().withProperty(UP, Boolean.valueOf(false)).withProperty(DOWN, Boolean.valueOf(false)).withProperty(NORTH, Boolean.valueOf(false)).withProperty(EAST, Boolean.valueOf(false)).withProperty(SOUTH, Boolean.valueOf(false)).withProperty(WEST, Boolean.valueOf(false)));
this.setTickRandomly(true);
this.setSoundType(SoundType.SLIME);
}
@SideOnly(Side.CLIENT)
@Override
public BlockRenderLayer getBlockLayer() {
return BlockRenderLayer.CUTOUT;
}
@Override
@javax.annotation.Nullable
public AxisAlignedBB getCollisionBoundingBox(IBlockState blockState, IBlockAccess worldIn, BlockPos pos) {
return NULL_AABB;
}
@Override
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos)
{
state = state.getActualState(source, pos);
int i = 0;
AxisAlignedBB axisalignedbb = FULL_BLOCK_AABB;
if (((Boolean)state.getValue(UP)).booleanValue())
{
axisalignedbb = UP_AABB;
++i;
}
if (((Boolean)state.getValue(DOWN)).booleanValue())
{
axisalignedbb = DOWN_AABB;
++i;
}
if (((Boolean)state.getValue(NORTH)).booleanValue())
{
axisalignedbb = NORTH_AABB;
++i;
}
if (((Boolean)state.getValue(EAST)).booleanValue())
{
axisalignedbb = EAST_AABB;
++i;
}
if (((Boolean)state.getValue(SOUTH)).booleanValue())
{
axisalignedbb = SOUTH_AABB;
++i;
}
if (((Boolean)state.getValue(WEST)).booleanValue())
{
axisalignedbb = WEST_AABB;
++i;
}
return i == 1 ? axisalignedbb : FULL_BLOCK_AABB;
}
/**
* Get the actual Block state of this Block at the given position. This applies properties not visible in the
* metadata, such as fence connections.
*/
@Override
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos)
{
return state.withProperty(UP, Boolean.valueOf(worldIn.getBlockState(pos.up()).getBlockFaceShape(worldIn, pos.up(), EnumFacing.DOWN) == BlockFaceShape.SOLID))
.withProperty(DOWN, Boolean.valueOf(worldIn.getBlockState(pos.down()).getBlockFaceShape(worldIn, pos.down(), EnumFacing.UP) == BlockFaceShape.SOLID))
.withProperty(NORTH, Boolean.valueOf(worldIn.getBlockState(pos.north()).getBlockFaceShape(worldIn, pos.north(), EnumFacing.SOUTH) == BlockFaceShape.SOLID))
.withProperty(SOUTH, Boolean.valueOf(worldIn.getBlockState(pos.south()).getBlockFaceShape(worldIn, pos.south(), EnumFacing.NORTH) == BlockFaceShape.SOLID))
.withProperty(EAST, Boolean.valueOf(worldIn.getBlockState(pos.east()).getBlockFaceShape(worldIn, pos.east(), EnumFacing.WEST) == BlockFaceShape.SOLID))
.withProperty(WEST, Boolean.valueOf(worldIn.getBlockState(pos.west()).getBlockFaceShape(worldIn, pos.west(), EnumFacing.EAST) == BlockFaceShape.SOLID));
}
/**
* Used to determine ambient occlusion and culling when rebuilding chunks for render
*/
@Override
public boolean isOpaqueCube(IBlockState state)
{
return false;
}
@Override
public boolean isFullCube(IBlockState state) {
return false;
}
/**
* Whether this Block can be replaced directly by other blocks (true for e.g. tall grass)
*/
@Override
public boolean isReplaceable(IBlockAccess worldIn, BlockPos pos)
{
return true;
}
/**
* Check whether this Block can be placed at pos, while aiming at the specified side of an adjacent block
*/
@Override
public boolean canPlaceBlockOnSide(World worldIn, BlockPos pos, EnumFacing side)
{
return side != EnumFacing.DOWN && side != EnumFacing.UP && this.canAttachTo(worldIn, pos, side);
}
/**
* Checks if this block can be placed exactly at the given position.
@Override
public boolean canPlaceBlockat(World worldIn, BlockPos pos)
{
for (EnumFacing enumfacing : EnumFacing.values())
{
if (canPlaceBlock(worldIn, pos, enumfacing))
{
return true;
}
}
return false;
}
*/
public boolean canAttachTo(World worldIn, BlockPos pos, EnumFacing facing)
{
Block block = worldIn.getBlockState(pos.up()).getBlock();
return this.isAcceptableNeighbor(worldIn, pos.offset(facing.getOpposite()), facing) && (block == Blocks.AIR || block == mcreator_creep.block || this.isAcceptableNeighbor(worldIn, pos.up(), EnumFacing.UP));
}
private boolean isAcceptableNeighbor(World worldIn, BlockPos pos, EnumFacing facing)
{
IBlockState iblockstate = worldIn.getBlockState(pos);
return iblockstate.getBlockFaceShape(worldIn, pos, facing) == BlockFaceShape.SOLID && !isExceptBlockForAttaching(iblockstate.getBlock());
}
protected static boolean isExceptBlockForAttaching(Block block)
{
return block == Blocks.AIR || block == Blocks.BEACON || block == Blocks.CAULDRON || block == Blocks.GLASS || block == Blocks.STAINED_GLASS || block == Blocks.PISTON || block == Blocks.STICKY_PISTON || block == Blocks.PISTON_HEAD || block == Blocks.TRAPDOOR;
}
private boolean recheckGrownSides(World worldIn, BlockPos pos, IBlockState state)
{
IBlockState iblockstate = state;
for (EnumFacing enumfacing : EnumFacing.Plane.HORIZONTAL)
{
PropertyBool propertybool = getPropertyFor(enumfacing);
if (((Boolean)state.getValue(propertybool)).booleanValue() && !this.canAttachTo(worldIn, pos, enumfacing.getOpposite()))
{
IBlockState iblockstate1 = worldIn.getBlockState(pos.up());
if (iblockstate1.getBlock() != this || !((Boolean)iblockstate1.getValue(propertybool)).booleanValue())
{
state = state.withProperty(propertybool, Boolean.valueOf(false));
}
}
}
if (getNumGrownFaces(state) == 0)
{
return false;
}
else
{
if (iblockstate != state)
{
worldIn.setBlockState(pos, state, 2);
}
return true;
}
}
/**
* Called when a neighboring block was changed and marks that this state should perform any checks during a neighbor
* change. Cases may include when redstone power is updated, cactus blocks popping off due to a neighboring solid
* block, etc.
*/
@Override
public void neighborChanged(IBlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos)
{
if (!worldIn.isRemote && !this.recheckGrownSides(worldIn, pos, state))
{
this.dropBlockAsItem(worldIn, pos, state, 0);
worldIn.setBlockToAir(pos);
}
}
@Override
public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
{
if (!worldIn.isRemote)
{
if (worldIn.rand.nextInt(4) == 0)
{
int i = 4;
int j = 5;
boolean flag = false;
label181:
for (int k = -4; k <= 4; ++k)
{
for (int l = -4; l <= 4; ++l)
{
for (int i1 = -1; i1 <= 1; ++i1)
{
if (worldIn.getBlockState(pos.add(k, i1, l)).getBlock() == this)
{
--j;
if (j <= 0)
{
flag = true;
break label181;
}
}
}
}
}
EnumFacing enumfacing1 = EnumFacing.random(rand);
BlockPos blockpos2 = pos.up();
if (enumfacing1 == EnumFacing.UP && pos.getY() < 255 && worldIn.isAirBlock(blockpos2))
{
IBlockState iblockstate2 = state;
for (EnumFacing enumfacing2 : EnumFacing.Plane.HORIZONTAL)
{
if (rand.nextBoolean() && this.canAttachTo(worldIn, blockpos2, enumfacing2.getOpposite()))
{
iblockstate2 = iblockstate2.withProperty(getPropertyFor(enumfacing2), Boolean.valueOf(true));
}
else
{
iblockstate2 = iblockstate2.withProperty(getPropertyFor(enumfacing2), Boolean.valueOf(false));
}
}
if (((Boolean)iblockstate2.getValue(NORTH)).booleanValue() || ((Boolean)iblockstate2.getValue(EAST)).booleanValue() || ((Boolean)iblockstate2.getValue(SOUTH)).booleanValue() || ((Boolean)iblockstate2.getValue(WEST)).booleanValue())
{
worldIn.setBlockState(blockpos2, iblockstate2, 2);
}
}
else if (enumfacing1.getAxis().isHorizontal() && !((Boolean)state.getValue(getPropertyFor(enumfacing1))).booleanValue())
{
if (!flag)
{
BlockPos blockpos4 = pos.offset(enumfacing1);
IBlockState iblockstate3 = worldIn.getBlockState(blockpos4);
Block block1 = iblockstate3.getBlock();
if (block1.isAir(iblockstate3, worldIn, blockpos4))
{
EnumFacing enumfacing3 = enumfacing1.rotateY();
EnumFacing enumfacing4 = enumfacing1.rotateYCCW();
boolean flag1 = ((Boolean)state.getValue(getPropertyFor(enumfacing3))).booleanValue();
boolean flag2 = ((Boolean)state.getValue(getPropertyFor(enumfacing4))).booleanValue();
BlockPos blockpos = blockpos4.offset(enumfacing3);
BlockPos blockpos1 = blockpos4.offset(enumfacing4);
if (flag1 && this.canAttachTo(worldIn, blockpos.offset(enumfacing3), enumfacing3))
{
worldIn.setBlockState(blockpos4, this.getDefaultState().withProperty(getPropertyFor(enumfacing3), Boolean.valueOf(true)), 2);
}
else if (flag2 && this.canAttachTo(worldIn, blockpos1.offset(enumfacing4), enumfacing4))
{
worldIn.setBlockState(blockpos4, this.getDefaultState().withProperty(getPropertyFor(enumfacing4), Boolean.valueOf(true)), 2);
}
else if (flag1 && worldIn.isAirBlock(blockpos) && this.canAttachTo(worldIn, blockpos, enumfacing1))
{
worldIn.setBlockState(blockpos, this.getDefaultState().withProperty(getPropertyFor(enumfacing1.getOpposite()), Boolean.valueOf(true)), 2);
}
else if (flag2 && worldIn.isAirBlock(blockpos1) && this.canAttachTo(worldIn, blockpos1, enumfacing1))
{
worldIn.setBlockState(blockpos1, this.getDefaultState().withProperty(getPropertyFor(enumfacing1.getOpposite()), Boolean.valueOf(true)), 2);
}
}
else if (iblockstate3.getBlockFaceShape(worldIn, blockpos4, enumfacing1) == BlockFaceShape.SOLID)
{
worldIn.setBlockState(pos, state.withProperty(getPropertyFor(enumfacing1), Boolean.valueOf(true)), 2);
}
}
}
else
{
if (pos.getY() > 1)
{
BlockPos blockpos3 = pos.down();
IBlockState iblockstate = worldIn.getBlockState(blockpos3);
Block block = iblockstate.getBlock();
if (block == Blocks.AIR)
{
IBlockState iblockstate1 = state;
for (EnumFacing enumfacing : EnumFacing.Plane.HORIZONTAL)
{
if (rand.nextBoolean())
{
iblockstate1 = iblockstate1.withProperty(getPropertyFor(enumfacing), Boolean.valueOf(false));
}
}
if (((Boolean)iblockstate1.getValue(NORTH)).booleanValue() || ((Boolean)iblockstate1.getValue(EAST)).booleanValue() || ((Boolean)iblockstate1.getValue(SOUTH)).booleanValue() || ((Boolean)iblockstate1.getValue(WEST)).booleanValue())
{
worldIn.setBlockState(blockpos3, iblockstate1, 2);
}
}
else if (block == this)
{
IBlockState iblockstate4 = iblockstate;
for (EnumFacing enumfacing5 : EnumFacing.Plane.HORIZONTAL)
{
PropertyBool propertybool = getPropertyFor(enumfacing5);
if (rand.nextBoolean() && ((Boolean)state.getValue(propertybool)).booleanValue())
{
iblockstate4 = iblockstate4.withProperty(propertybool, Boolean.valueOf(true));
}
}
if (((Boolean)iblockstate4.getValue(NORTH)).booleanValue() || ((Boolean)iblockstate4.getValue(EAST)).booleanValue() || ((Boolean)iblockstate4.getValue(SOUTH)).booleanValue() || ((Boolean)iblockstate4.getValue(WEST)).booleanValue())
{
worldIn.setBlockState(blockpos3, iblockstate4, 2);
}
}
}
}
}
}
}
/**
* Called by ItemBlocks just before a block is actually set in the world, to allow for adjustments to the
* IBlockstate
*/
public IBlockState getStateForPlacement(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer)
{
IBlockState iblockstate = this.getDefaultState().withProperty(UP, Boolean.valueOf(false)).withProperty(DOWN, Boolean.valueOf(false)).withProperty(NORTH, Boolean.valueOf(false)).withProperty(EAST, Boolean.valueOf(false)).withProperty(SOUTH, Boolean.valueOf(false)).withProperty(WEST, Boolean.valueOf(false));
return facing.getAxis().isHorizontal() ? iblockstate.withProperty(getPropertyFor(facing.getOpposite()), Boolean.valueOf(true)) : iblockstate;
}
@Override
public int tickRate(World world) {
return 10;
}
@Override
public IBlockState getStateFromMeta(int meta)
{
return this.getDefaultState().withProperty(SOUTH, Boolean.valueOf((meta & 1) > 0)).withProperty(WEST, Boolean.valueOf((meta & 2) > 0)).withProperty(UP, Boolean.valueOf((meta & 3) > 0)).withProperty(NORTH, Boolean.valueOf((meta & 4) > 0)).withProperty(DOWN, Boolean.valueOf((meta & 5) > 0)).withProperty(EAST, Boolean.valueOf((meta & 8) > 0));
}
/**
* Convert the BlockState into the correct metadata value
*/
@Override
public int getMetaFromState(IBlockState state)
{
int i = 0;
if (((Boolean)state.getValue(SOUTH)).booleanValue())
{
i |= 1;
}
if (((Boolean)state.getValue(WEST)).booleanValue())
{
i |= 2;
}
if (((Boolean)state.getValue(UP)).booleanValue())
{
i |= 3;
}
if (((Boolean)state.getValue(NORTH)).booleanValue())
{
i |= 4;
}
if (((Boolean)state.getValue(DOWN)).booleanValue())
{
i |= 5;
}
if (((Boolean)state.getValue(EAST)).booleanValue())
{
i |= 8;
}
return i;
}
protected BlockStateContainer createBlockState()
{
return new BlockStateContainer(this, new IProperty[] {UP, DOWN, NORTH, EAST, SOUTH, WEST});
}
/**
* Returns the blockstate with the given rotation from the passed blockstate. If inapplicable, returns the passed
* blockstate.
*/
public IBlockState withRotation(IBlockState state, Rotation rot)
{
switch (rot)
{
case CLOCKWISE_180:
return state.withProperty(NORTH, state.getValue(SOUTH)).withProperty(EAST, state.getValue(WEST)).withProperty(SOUTH, state.getValue(NORTH)).withProperty(WEST, state.getValue(EAST));
case COUNTERCLOCKWISE_90:
return state.withProperty(NORTH, state.getValue(EAST)).withProperty(EAST, state.getValue(SOUTH)).withProperty(SOUTH, state.getValue(WEST)).withProperty(WEST, state.getValue(NORTH));
case CLOCKWISE_90:
return state.withProperty(NORTH, state.getValue(WEST)).withProperty(EAST, state.getValue(NORTH)).withProperty(SOUTH, state.getValue(EAST)).withProperty(WEST, state.getValue(SOUTH));
default:
return state;
}
}
/**
* Returns the blockstate with the given mirror of the passed blockstate. If inapplicable, returns the passed
* blockstate.
*/
public IBlockState withMirror(IBlockState state, Mirror mirrorIn)
{
switch (mirrorIn)
{
case LEFT_RIGHT:
return state.withProperty(NORTH, state.getValue(SOUTH)).withProperty(SOUTH, state.getValue(NORTH));
case FRONT_BACK:
return state.withProperty(EAST, state.getValue(WEST)).withProperty(WEST, state.getValue(EAST));
default:
return super.withMirror(state, mirrorIn);
}
}
public static PropertyBool getPropertyFor(EnumFacing side)
{
switch (side)
{
case UP:
return UP;
case DOWN:
return DOWN;
case NORTH:
return NORTH;
case SOUTH:
return SOUTH;
case WEST:
return WEST;
case EAST:
return EAST;
default:
return DOWN;
}
}
public static int getNumGrownFaces(IBlockState state)
{
int i = 0;
for (PropertyBool propertybool : ALL_FACES)
{
if (((Boolean)state.getValue(propertybool)).booleanValue())
{
++i;
}
}
return i;
}
@Override
public int quantityDropped(Random par1Random) {
return 1;
}
@Override
public Item getItemDropped(IBlockState state, Random par2Random, int par3) {
return new ItemStack(Items.ROTTEN_FLESH).getItem();
}
@Override
public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face)
{
return BlockFaceShape.UNDEFINED;
}
}
So I have been working on teaching myself modding for the past few days in an attempt to put forth a concept I had.
Basically, it adds in a growth that spreads across blocks, with the goal to have it behave similar to the taint in Thaumcraft, with the idea being you can command this growth, similar to the Creep in Starcraft.
To that end, I have named this block Creep.
I would appreciate help with understanding this. I think I need to define the textures in the script? But as I said, I am literally teaching myself how to do this, so I'm not sure. Below is the code for the Creep Block