I suppose you already have the MainClass, and stuff like that. But if you want, I can do the other tutorials from the beginning of mod, stuff like, java setup, eclipse, and other. And, more one thing, my bad English is because i'm brazilian (my native language is Brazilian Portuguese) and too because i learned English in games and reading manga. Then, sorry if i wrote some word incorrectly. I tried my best.
First of all, we need to create a dimension, after this, the portal.
Firstly, you have to give a id for your dimension, we can do do this in the MainClass.
MainClass
This is my MainClass.
package TestMod;
@Mod(modid = MainClass.modId, name = "Test Mod", version = "1.33.324")
public class MainClass
{
@SidedProxy(serverSide = "TestMod.CommonProxy", clientSide = "TestMod.ClientProxy")
public static CommonProxy proxy;
public static final String modId = "testmod";
@EventHandler
public void preInit(FMLPreInitializationEvent event)
{
ModBlocks.init();
ModItems.init();
}
@EventHandler
public void init(FMLInitializationEvent event)
{
}
@EventHandler
public void postInit(FMLPostInitializationEvent event)
{
}
}
For put the dimension id, paste this code
public static int dimId = 3;
Can be number "3", for example, can be other number, less, 0, 1 or -1, because these ids are the worlds of Minecraft. And put that code, before your
public void preInit...
And in the final, your MainClass need to be like this.
package TestMod;
@Mod(modid = MainClass.modId, name = "Test Mod", version = "1.33.324")
public class MainClass
{
@SidedProxy(serverSide = "TestMod.CommonProxy", clientSide = "TestMod.ClientProxy")
public static CommonProxy proxy;
public static final String modId = "testmod";
public static int dimId = 3;
@EventHandler
public void preInit(FMLPreInitializationEvent event)
{
ModBlocks.init();
ModItems.init();
}
@EventHandler
public void init(FMLInitializationEvent event)
{
}
@EventHandler
public void postInit(FMLPostInitializationEvent event)
{
}
Now we go make a class, let's name this of ModDimensions. In this class, we are register the dimension type and the dimension.
ModDimensions.class
public class ModDimensions {
public static DimensionType testDimensionType;
public static final DimensionType TEST_DIMENSION = DimensionType.register("TEST", "_test", MainClass.dimId, TestWorldProvider.class, false);
public static void init() {
registerDimensions();
}
private static void registerDimensions() {
DimensionManager.registerDimension(MainClass.dimId, TEST_DIMENSION);
}
}
You can change "test" for the name of your dimension.
Let's go make the Teleporter, and a TileEntity for use NBT.
TestTeleporter.Class
public class TestTeleporter extends Teleporter
{
public int dme;
private final WorldServer worldServerInstance;
private final Random random;
private double prevY, prevX, prevZ;
private final Long2ObjectMap<TestTeleporter.PortalPosition> destinationCoordinateCache = new Long2ObjectOpenHashMap(4096);
public TestTeleporter(WorldServer worldIn, int dme2, double x, double y, double z)
{
super(worldIn);
this.worldServerInstance = worldIn;
this.random = new Random(worldIn.getSeed());
this.dme = dme2;
this.prevX = x;
this.prevY = y;
this.prevZ = z;
}
public void placeInPortal(Entity entityIn, float rotationYaw)
{
if(dme < 2)
{
this.makePortal(entityIn);
}
else if(dme > 1)
{
entityIn.setLocationAndAngles(prevX, prevY, prevZ, entityIn.rotationYaw, 0.0F);
entityIn.motionX = 0.5D;
entityIn.motionY = 0.0D;
entityIn.motionZ = 0.5D;
}
}
public boolean placeInExistingPortal(Entity entityIn, float rotationYaw)
{
return false;
}
public boolean makePortal(Entity entityIn)
{
int i = 16;
double d0 = -1.0D;
int j = MathHelper.floor_double(entityIn.posX);
int k = MathHelper.floor_double(entityIn.posY);
int l = MathHelper.floor_double(entityIn.posZ);
int i1 = j;
int j1 = k;
int k1 = l;
int l1 = 0;
int i2 = this.random.nextInt(4);
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
for (int j2 = j - 16; j2 <= j + 16; ++j2)
{
double d1 = (double)j2 + 0.5D - entityIn.posX;
for (int l2 = l - 16; l2 <= l + 16; ++l2)
{
double d2 = (double)l2 + 0.5D - entityIn.posZ;
label146:
for (int j3 = this.worldServerInstance.getActualHeight() - 1; j3 >= 0; --j3)
{
if (this.worldServerInstance.isAirBlock(blockpos$mutableblockpos.setPos(j2, j3, l2)))
{
while (j3 > 0 && this.worldServerInstance.isAirBlock(blockpos$mutableblockpos.setPos(j2, j3 - 1, l2)))
{
--j3;
}
for (int k3 = i2; k3 < i2 + 4; ++k3)
{
int l3 = k3 % 2;
int i4 = 1 - l3;
if (k3 % 4 >= 2)
{
l3 = -l3;
i4 = -i4;
}
for (int j4 = 0; j4 < 3; ++j4)
{
for (int k4 = 0; k4 < 4; ++k4)
{
for (int l4 = -1; l4 < 4; ++l4)
{
int i5 = j2 + (k4 - 1) * l3 + j4 * i4;
int j5 = j3 + l4;
int k5 = l2 + (k4 - 1) * i4 - j4 * l3;
blockpos$mutableblockpos.setPos(i5, j5, k5);
if (l4 < 0 && !this.worldServerInstance.getBlockState(blockpos$mutableblockpos).getMaterial().isSolid() || l4 >= 0 && !this.worldServerInstance.isAirBlock(blockpos$mutableblockpos))
{
continue label146;
}
}
}
}
double d5 = (double)j3 + 0.5D - entityIn.posY;
double d7 = d1 * d1 + d5 * d5 + d2 * d2;
if (d0 < 0.0D || d7 < d0)
{
d0 = d7;
i1 = j2;
j1 = j3;
k1 = l2;
l1 = k3 % 4;
}
}
}
}
}
}
if (d0 < 0.0D)
{
for (int l5 = j - 16; l5 <= j + 16; ++l5)
{
double d3 = (double)l5 + 0.5D - entityIn.posX;
for (int j6 = l - 16; j6 <= l + 16; ++j6)
{
double d4 = (double)j6 + 0.5D - entityIn.posZ;
label567:
for (int i7 = this.worldServerInstance.getActualHeight() - 1; i7 >= 0; --i7)
{
if (this.worldServerInstance.isAirBlock(blockpos$mutableblockpos.setPos(l5, i7, j6)))
{
while (i7 > 0 && this.worldServerInstance.isAirBlock(blockpos$mutableblockpos.setPos(l5, i7 - 1, j6)))
{
--i7;
}
for (int k7 = i2; k7 < i2 + 2; ++k7)
{
int j8 = k7 % 2;
int j9 = 1 - j8;
for (int j10 = 0; j10 < 4; ++j10)
{
for (int j11 = -1; j11 < 4; ++j11)
{
int j12 = l5 + (j10 - 1) * j8;
int i13 = i7 + j11;
int j13 = j6 + (j10 - 1) * j9;
blockpos$mutableblockpos.setPos(j12, i13, j13);
if (j11 < 0 && !this.worldServerInstance.getBlockState(blockpos$mutableblockpos).getMaterial().isSolid() || j11 >= 0 && !this.worldServerInstance.isAirBlock(blockpos$mutableblockpos))
{
continue label567;
}
}
}
double d6 = (double)i7 + 0.5D - entityIn.posY;
double d8 = d3 * d3 + d6 * d6 + d4 * d4;
if (d0 < 0.0D || d8 < d0)
{
d0 = d8;
i1 = l5;
j1 = i7;
k1 = j6;
l1 = k7 % 2;
}
}
}
}
}
}
}
int i6 = i1;
int k2 = j1;
int k6 = k1;
int l6 = l1 % 2;
int i3 = 1 - l6;
if (l1 % 4 >= 2)
{
l6 = -l6;
i3 = -i3;
}
if (d0 < 0.0D)
{
j1 = MathHelper.clamp_int(j1, 70, this.worldServerInstance.getActualHeight() - 10);
k2 = j1;
for (int j7 = -1; j7 <= 1; ++j7)
{
for (int l7 = 1; l7 < 3; ++l7)
{
for (int k8 = -1; k8 < 3; ++k8)
{
int k9 = i6 + (l7 - 1) * l6 + j7 * i3;
int k10 = k2 + k8;
int k11 = k6 + (l7 - 1) * i3 - j7 * l6;
boolean flag = k8 < 0;
this.worldServerInstance.setBlockState(new BlockPos(k9, k10, k11), flag ? Blocks.STONE.getDefaultState() : Blocks.AIR.getDefaultState());
}
}
}
}
IBlockState iblockstate = ModBlocks.customBlock.getDefaultState().withProperty(BlockPortal.AXIS, l6 == 0 ? EnumFacing.Axis.Z : EnumFacing.Axis.X);
for (int i8 = 0; i8 < 4; ++i8)
{
for (int l8 = 0; l8 < 4; ++l8)
{
for (int l9 = -1; l9 < 4; ++l9)
{
int l10 = i6 + (l8 - 1) * l6;
int l11 = k2 + l9;
int k12 = k6 + (l8 - 1) * i3;
boolean flag1 = l8 == 0 || l8 == 3 || l9 == -1 || l9 == 3;
this.worldServerInstance.setBlockState(new BlockPos(l10, l11, k12), flag1 ? Blocks.STONE.getDefaultState() : iblockstate, 2);
entityIn.setLocationAndAngles(l10, l11, k12, entityIn.rotationYaw, entityIn.rotationPitch);
}
}
for (int i9 = 0; i9 < 4; ++i9)
{
for (int i10 = -1; i10 < 4; ++i10)
{
int i11 = i6 + (i9 - 1) * l6;
int i12 = k2 + i10;
int l12 = k6 + (i9 - 1) * i3;
BlockPos blockpos = new BlockPos(i11, i12, l12);
this.worldServerInstance.notifyNeighborsOfStateChange(blockpos, this.worldServerInstance.getBlockState(blockpos).getBlock());
}
}
}
return true;
}
public class PortalPosition extends BlockPos
{
/** The worldtime at which this PortalPosition was last verified */
public long lastUpdateTime;
public PortalPosition(BlockPos pos, long lastUpdate)
{
super(pos.getX(), pos.getY(), pos.getZ());
this.lastUpdateTime = lastUpdate;
}
}
}
Use Ctrl+F and search for Blocks.STONE and change this for your block that you use for make the portal. And too, change ModBlocks.customBlock for your portal block, we still need to create him.
public class TestWorldProvider extends WorldProvider
{
public void registerWorldChunkManager()
{
this.biomeProvider = new BiomeProviderSingle(Biomes.VOID);
this.setDimension(MainClass.dimId);
this.setAllowedSpawnTypes(false, false);
this.hasNoSky = false;
}
@Override
public IChunkGenerator createChunkGenerator()
{
return new TestChunkGenerator(this.worldObj);
}
public Biome getBiomeGenForCoords(BlockPos pos)
{
return Biomes.VOID;
}
@Override
public boolean canRespawnHere()
{
return true;
}
@Override
public int getRespawnDimension(EntityPlayerMP player)
{
return MainClass.dimId;
}
@Override
public boolean isSurfaceWorld()
{
return true;
}
@Override
public String getWelcomeMessage()
{
return "Entering your Tent";
}
@Override
public DimensionType getDimensionType()
{
return ModDimensions.TEST_DIMENSION;
}
}
These three compose the world. And will go to generate a world like the Overworld of minecraft. With all that things, your dimension is ready to enter. But now, you need a method for enter. You can make other things instead of an portal, but, in this thread i will go explain how to make the portal.
For make the portal works, we need a custom fire, a custom flint and steel, a custom portal block, and if you want some block that you created for making the structure of portal. First, let's create the portal.
This class is the my custom block portal.
public class CustomBlock extends BlockPortal
{
public static String name;
public static final PropertyEnum<EnumFacing.Axis> AXIS = PropertyEnum.<EnumFacing.Axis>create("axis", EnumFacing.Axis.class, new EnumFacing.Axis[] {EnumFacing.Axis.X, EnumFacing.Axis.Z});
protected static final AxisAlignedBB X_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.375D, 1.0D, 1.0D, 0.625D);
protected static final AxisAlignedBB Z_AABB = new AxisAlignedBB(0.375D, 0.0D, 0.0D, 0.625D, 1.0D, 1.0D);
protected static final AxisAlignedBB Y_AABB = new AxisAlignedBB(0.375D, 0.0D, 0.375D, 0.625D, 1.0D, 0.625D);
protected CustomBlock(String name, CreativeTabs tab)
{
super();
this.name = name;
this.setDefaultState(this.blockState.getBaseState().withProperty(AXIS, EnumFacing.Axis.X));
this.setTickRandomly(true);
setUnlocalizedName(name);
setRegistryName(name);
setCreativeTab(tab);
}
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos)
{
switch ((EnumFacing.Axis)state.getValue(AXIS))
{
case X:
return X_AABB;
case Y:
default:
return Y_AABB;
case Z:
return Z_AABB;
}
}
public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
{
super.updateTick(worldIn, pos, state, rand);
if (worldIn.provider.isSurfaceWorld() && worldIn.getGameRules().getBoolean("doMobSpawning") && rand.nextInt(2000) < worldIn.getDifficulty().getDifficultyId())
{
int i = pos.getY();
BlockPos blockpos;
for (blockpos = pos; !worldIn.getBlockState(blockpos).isFullyOpaque() && blockpos.getY() > 0; blockpos = blockpos.down())
{
;
}
if (i > 0 && !worldIn.getBlockState(blockpos.up()).isNormalCube())
{
Entity entity = ItemMonsterPlacer.spawnCreature(worldIn, EntityList.getEntityStringFromClass(EntityPigZombie.class), (double)blockpos.getX() + 0.5D, (double)blockpos.getY() + 1.1D, (double)blockpos.getZ() + 0.5D);
if (entity != null)
{
entity.timeUntilPortal = entity.getPortalCooldown();
}
}
}
}
@Nullable
public AxisAlignedBB getCollisionBoundingBox(IBlockState blockState, World worldIn, BlockPos pos)
{
return NULL_AABB;
}
public static int getMetaForAxis(EnumFacing.Axis axis)
{
return axis == EnumFacing.Axis.X ? 1 : (axis == EnumFacing.Axis.Z ? 2 : 0);
}
public boolean isFullCube(IBlockState state)
{
return false;
}
public boolean trySpawnPortal(World worldIn, BlockPos pos)
{
CustomBlock.Size blockportal$size = new CustomBlock.Size(worldIn, pos, EnumFacing.Axis.X);
if (blockportal$size.isValid() && blockportal$size.portalBlockCount == 0)
{
blockportal$size.placePortalBlocks();
return true;
}
else
{
CustomBlock.Size blockportal$size1 = new CustomBlock.Size(worldIn, pos, EnumFacing.Axis.Z);
if (blockportal$size1.isValid() && blockportal$size1.portalBlockCount == 0)
{
blockportal$size1.placePortalBlocks();
return true;
}
else
{
return false;
}
}
}
/**
* 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.
*/
public void neighborChanged(IBlockState state, World worldIn, BlockPos pos, Block blockIn)
{
EnumFacing.Axis enumfacing$axis = (EnumFacing.Axis)state.getValue(AXIS);
if (enumfacing$axis == EnumFacing.Axis.X)
{
CustomBlock.Size blockportal$size = new CustomBlock.Size(worldIn, pos, EnumFacing.Axis.X);
if (!blockportal$size.isValid() || blockportal$size.portalBlockCount < blockportal$size.width * blockportal$size.height)
{
worldIn.setBlockState(pos, Blocks.AIR.getDefaultState());
}
}
else if (enumfacing$axis == EnumFacing.Axis.Z)
{
CustomBlock.Size blockportal$size1 = new CustomBlock.Size(worldIn, pos, EnumFacing.Axis.Z);
if (!blockportal$size1.isValid() || blockportal$size1.portalBlockCount < blockportal$size1.width * blockportal$size1.height)
{
worldIn.setBlockState(pos, Blocks.AIR.getDefaultState());
}
}
}
@SideOnly(Side.CLIENT)
public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos, EnumFacing side)
{
pos = pos.offset(side);
EnumFacing.Axis enumfacing$axis = null;
if (blockState.getBlock() == this)
{
enumfacing$axis = (EnumFacing.Axis)blockState.getValue(AXIS);
if (enumfacing$axis == null)
{
return false;
}
if (enumfacing$axis == EnumFacing.Axis.Z && side != EnumFacing.EAST && side != EnumFacing.WEST)
{
return false;
}
if (enumfacing$axis == EnumFacing.Axis.X && side != EnumFacing.SOUTH && side != EnumFacing.NORTH)
{
return false;
}
}
boolean flag = blockAccess.getBlockState(pos.west()).getBlock() == this && blockAccess.getBlockState(pos.west(2)).getBlock() != this;
boolean flag1 = blockAccess.getBlockState(pos.east()).getBlock() == this && blockAccess.getBlockState(pos.east(2)).getBlock() != this;
boolean flag2 = blockAccess.getBlockState(pos.north()).getBlock() == this && blockAccess.getBlockState(pos.north(2)).getBlock() != this;
boolean flag3 = blockAccess.getBlockState(pos.south()).getBlock() == this && blockAccess.getBlockState(pos.south(2)).getBlock() != this;
boolean flag4 = flag || flag1 || enumfacing$axis == EnumFacing.Axis.X;
boolean flag5 = flag2 || flag3 || enumfacing$axis == EnumFacing.Axis.Z;
return flag4 && side == EnumFacing.WEST ? true : (flag4 && side == EnumFacing.EAST ? true : (flag5 && side == EnumFacing.NORTH ? true : flag5 && side == EnumFacing.SOUTH));
}
/**
* Returns the quantity of items to drop on block destruction.
*/
public int quantityDropped(Random random)
{
return 0;
}
public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, IBlockState state, Entity entityIn)
{
if ((entityIn.getRidingEntity() == null) && ((entityIn instanceof EntityPlayerMP)))
{
EntityPlayerMP player1 = (EntityPlayerMP)entityIn;
TileEntityDim.tele(player1);
}
}
@Nullable
public ItemStack getItem(World worldIn, BlockPos pos, IBlockState state)
{
return null;
}
/**
* Convert the given metadata into a BlockState for this Block
*/
public IBlockState getStateFromMeta(int meta)
{
return this.getDefaultState().withProperty(AXIS, (meta & 3) == 2 ? EnumFacing.Axis.Z : EnumFacing.Axis.X);
}
@SideOnly(Side.CLIENT)
public BlockRenderLayer getBlockLayer()
{
return BlockRenderLayer.TRANSLUCENT;
}
@SideOnly(Side.CLIENT)
public void randomDisplayTick(IBlockState stateIn, World worldIn, BlockPos pos, Random rand)
{
if (rand.nextInt(100) == 0)
{
worldIn.playSound((double)pos.getX() + 0.5D, (double)pos.getY() + 0.5D, (double)pos.getZ() + 0.5D, SoundEvents.BLOCK_PORTAL_AMBIENT, SoundCategory.BLOCKS, 0.5F, rand.nextFloat() * 0.4F + 0.8F, false);
}
for (int i = 0; i < 4; ++i)
{
double d0 = (double)((float)pos.getX() + rand.nextFloat());
double d1 = (double)((float)pos.getY() + rand.nextFloat());
double d2 = (double)((float)pos.getZ() + rand.nextFloat());
double d3 = ((double)rand.nextFloat() - 0.5D) * 0.5D;
double d4 = ((double)rand.nextFloat() - 0.5D) * 0.5D;
double d5 = ((double)rand.nextFloat() - 0.5D) * 0.5D;
int j = rand.nextInt(2) * 2 - 1;
if (worldIn.getBlockState(pos.west()).getBlock() != this && worldIn.getBlockState(pos.east()).getBlock() != this)
{
d0 = (double)pos.getX() + 0.5D + 0.25D * (double)j;
d3 = (double)(rand.nextFloat() * 2.0F * (float)j);
}
else
{
d2 = (double)pos.getZ() + 0.5D + 0.25D * (double)j;
d5 = (double)(rand.nextFloat() * 2.0F * (float)j);
}
worldIn.spawnParticle(EnumParticleTypes.PORTAL, d0, d1, d2, d3, d4, d5, new int[0]);
}
}
/**
* Convert the BlockState into the correct metadata value
*/
public int getMetaFromState(IBlockState state)
{
return getMetaForAxis((EnumFacing.Axis)state.getValue(AXIS));
}
/**
* 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 COUNTERCLOCKWISE_90:
case CLOCKWISE_90:
switch ((EnumFacing.Axis)state.getValue(AXIS))
{
case X:
return state.withProperty(AXIS, EnumFacing.Axis.Z);
case Z:
return state.withProperty(AXIS, EnumFacing.Axis.X);
default:
return state;
}
default:
return state;
}
}
protected BlockStateContainer createBlockState()
{
return new BlockStateContainer(this, new IProperty[] {AXIS});
}
public BlockPattern.PatternHelper createPatternHelper(World worldIn, BlockPos p_181089_2_)
{
EnumFacing.Axis enumfacing$axis = EnumFacing.Axis.Z;
CustomBlock.Size blockportal$size = new CustomBlock.Size(worldIn, p_181089_2_, EnumFacing.Axis.X);
LoadingCache<BlockPos, BlockWorldState> loadingcache = BlockPattern.createLoadingCache(worldIn, true);
if (!blockportal$size.isValid())
{
enumfacing$axis = EnumFacing.Axis.X;
blockportal$size = new CustomBlock.Size(worldIn, p_181089_2_, EnumFacing.Axis.Z);
}
if (!blockportal$size.isValid())
{
return new BlockPattern.PatternHelper(p_181089_2_, EnumFacing.NORTH, EnumFacing.UP, loadingcache, 1, 1, 1);
}
else
{
int[] aint = new int[EnumFacing.AxisDirection.values().length];
EnumFacing enumfacing = blockportal$size.rightDir.rotateYCCW();
BlockPos blockpos = blockportal$size.bottomLeft.up(blockportal$size.getHeight() - 1);
for (EnumFacing.AxisDirection enumfacing$axisdirection : EnumFacing.AxisDirection.values())
{
BlockPattern.PatternHelper blockpattern$patternhelper = new BlockPattern.PatternHelper(enumfacing.getAxisDirection() == enumfacing$axisdirection ? blockpos : blockpos.offset(blockportal$size.rightDir, blockportal$size.getWidth() - 1), EnumFacing.getFacingFromAxis(enumfacing$axisdirection, enumfacing$axis), EnumFacing.UP, loadingcache, blockportal$size.getWidth(), blockportal$size.getHeight(), 1);
for (int i = 0; i < blockportal$size.getWidth(); ++i)
{
for (int j = 0; j < blockportal$size.getHeight(); ++j)
{
BlockWorldState blockworldstate = blockpattern$patternhelper.translateOffset(i, j, 1);
if (blockworldstate.getBlockState() != null && blockworldstate.getBlockState().getMaterial() != Material.AIR)
{
++aint[enumfacing$axisdirection.ordinal()];
}
}
}
}
EnumFacing.AxisDirection enumfacing$axisdirection1 = EnumFacing.AxisDirection.POSITIVE;
for (EnumFacing.AxisDirection enumfacing$axisdirection2 : EnumFacing.AxisDirection.values())
{
if (aint[enumfacing$axisdirection2.ordinal()] < aint[enumfacing$axisdirection1.ordinal()])
{
enumfacing$axisdirection1 = enumfacing$axisdirection2;
}
}
return new BlockPattern.PatternHelper(enumfacing.getAxisDirection() == enumfacing$axisdirection1 ? blockpos : blockpos.offset(blockportal$size.rightDir, blockportal$size.getWidth() - 1), EnumFacing.getFacingFromAxis(enumfacing$axisdirection1, enumfacing$axis), EnumFacing.UP, loadingcache, blockportal$size.getWidth(), blockportal$size.getHeight(), 1);
}
}
public static class Size
{
private final World world;
private final EnumFacing.Axis axis;
private final EnumFacing rightDir;
private final EnumFacing leftDir;
private int portalBlockCount;
private BlockPos bottomLeft;
private int height;
private int width;
public Size(World worldIn, BlockPos p_i45694_2_, EnumFacing.Axis p_i45694_3_)
{
this.world = worldIn;
this.axis = p_i45694_3_;
if (p_i45694_3_ == EnumFacing.Axis.X)
{
this.leftDir = EnumFacing.EAST;
this.rightDir = EnumFacing.WEST;
}
else
{
this.leftDir = EnumFacing.NORTH;
this.rightDir = EnumFacing.SOUTH;
}
for (BlockPos blockpos = p_i45694_2_; p_i45694_2_.getY() > blockpos.getY() - 21 && p_i45694_2_.getY() > 0 && this.isEmptyBlock(worldIn.getBlockState(p_i45694_2_.down()).getBlock()); p_i45694_2_ = p_i45694_2_.down())
{
;
}
int i = this.getDistanceUntilEdge(p_i45694_2_, this.leftDir) - 1;
if (i >= 0)
{
this.bottomLeft = p_i45694_2_.offset(this.leftDir, i);
this.width = this.getDistanceUntilEdge(this.bottomLeft, this.rightDir);
if (this.width < 2 || this.width > 21)
{
this.bottomLeft = null;
this.width = 0;
}
}
if (this.bottomLeft != null)
{
this.height = this.calculatePortalHeight();
}
}
protected int getDistanceUntilEdge(BlockPos p_180120_1_, EnumFacing p_180120_2_)
{
int i;
for (i = 0; i < 22; ++i)
{
BlockPos blockpos = p_180120_1_.offset(p_180120_2_, i);
if (!this.isEmptyBlock(this.world.getBlockState(blockpos).getBlock()) || this.world.getBlockState(blockpos.down()).getBlock() != Blocks.STONE)
{
break;
}
}
Block block = this.world.getBlockState(p_180120_1_.offset(p_180120_2_, i)).getBlock();
return block == Blocks.STONE ? i : 0;
}
public int getHeight()
{
return this.height;
}
public int getWidth()
{
return this.width;
}
protected int calculatePortalHeight()
{
label24:
for (this.height = 0; this.height < 21; ++this.height)
{
for (int i = 0; i < this.width; ++i)
{
BlockPos blockpos = this.bottomLeft.offset(this.rightDir, i).up(this.height);
Block block = this.world.getBlockState(blockpos).getBlock();
if (!this.isEmptyBlock(block))
{
break label24;
}
if (block == ModBlocks.customBlock)
{
++this.portalBlockCount;
}
if (i == 0)
{
block = this.world.getBlockState(blockpos.offset(this.leftDir)).getBlock();
if (block != Blocks.STONE)
{
break label24;
}
}
else if (i == this.width - 1)
{
block = this.world.getBlockState(blockpos.offset(this.rightDir)).getBlock();
if (block != Blocks.STONE)
{
break label24;
}
}
}
}
for (int j = 0; j < this.width; ++j)
{
if (this.world.getBlockState(this.bottomLeft.offset(this.rightDir, j).up(this.height)).getBlock() != Blocks.STONE)
{
this.height = 0;
break;
}
}
if (this.height <= 21 && this.height >= 3)
{
return this.height;
}
else
{
this.bottomLeft = null;
this.width = 0;
this.height = 0;
return 0;
}
}
protected boolean isEmptyBlock(Block blockIn)
{
return blockIn.getMaterial(null) == Material.AIR || blockIn == ModBlocks.testFire || blockIn == ModBlocks.customBlock;
}
public boolean isValid()
{
return this.bottomLeft != null && this.width >= 2 && this.width <= 21 && this.height >= 3 && this.height <= 21;
}
public void placePortalBlocks()
{
for (int i = 0; i < this.width; ++i)
{
BlockPos blockpos = this.bottomLeft.offset(this.rightDir, i);
for (int j = 0; j < this.height; ++j)
{
this.world.setBlockState(blockpos.up(j), ModBlocks.customBlock.getDefaultState().withProperty(CustomBlock.AXIS, this.axis), 2);
}
}
}
}
public void rgRender(ItemBlock itemblock)
{
MainClass.proxy.rgItemsRender(itemblock, 0, name);
}
}
Use Ctrl+F and search for CustomBlock, and change this for the name of your class. And search for ModBlocks.customBlock and change it to the register that you make in the class ModBlocks (if you following other tutorials in this forum, you are understanding me, but, case you have any doubt, ask me). And your ModBlocks class, these blocks we are creating, they don't need a different type of register, they are like this "customBlock = register(new CustomBlock("customBlock", CreativeTabs.REDSTONE));" for example. Before i forget, you need too search for ModBlocks.testFire and change it for the register that you maked in ModBlocks for your custom fire, example: "ModBlocks.customFire". And too, change "Blocks.STONE" to the block what you want to make the portal.
Again, use Ctrl+F and search for ModBlocks.customBlock and change it for the block you create a few minutes ago, but, of course, subtitute ModBlocks.customBlock for "ModBlocks.yourblockhere".
And for last, we need to create the flint for put fire in things.
This my custom flint class.
public class TestFlint extends Item
{
public static String name;
public TestFlint(String name)
{
this.name = name;
setUnlocalizedName(name);
setRegistryName(name);
this.maxStackSize = 1;
this.setMaxDamage(64);
this.setCreativeTab(CreativeTabs.TOOLS);
}
/**
* Called when a Block is right-clicked with this Item
*/
public EnumActionResult onItemUse(ItemStack stack, EntityPlayer playerIn, World worldIn, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
{
pos = pos.offset(facing);
if (!playerIn.canPlayerEdit(pos, facing, stack))
{
return EnumActionResult.FAIL;
}
else
{
if (worldIn.isAirBlock(pos))
{
worldIn.playSound(playerIn, pos, SoundEvents.ITEM_FLINTANDSTEEL_USE, SoundCategory.BLOCKS, 1.0F, itemRand.nextFloat() * 0.4F + 0.8F);
worldIn.setBlockState(pos, ModBlocks.testFire.getDefaultState(), 11);
}
stack.damageItem(1, playerIn);
return EnumActionResult.SUCCESS;
}
}
}
It's very easy to configure this block, use Ctrl+F search for "ModBlocks.testFire" and change it to your register of the block fire you created, example: "ModBlocks.customFire", remember, put the methods of register render for making the texture of items and blocks appears, you need to know how to create blocks and items. If you are following the other tutorials in this forum, you already know this.
That's all. My tutorial is finished here. Sorry my bad English, i already explained my reason for it. Maybe i will create a new tutorial about crops, or something like that... Bye.
Could you paste your LythrmTeleporter file on here? NullPointerException means that you're referencing to a variable that has no assigned value. I don't see what Teleporter.<init> is referring to, but if you could track what value is being used to carry over from TileEntityTele.tele to LythrmTeleporter.<init>, it will probably tell you what is wrong. I don't know what is exactly wrong because I don't have the last 5 lines of the stacktrace and don't know your program.
I would recommend that instead of hard coding the id, you instead use DimensionManager.getNextFreeDimId(), as that will prevent two different mods using the same dimension id. I would also recommend setting all references to the dimension id to the dimension id variable.
package TestMod;
For put the dimension id, paste this code
Can be number "3", for example, can be other number, less, 0, 1 or -1, because these ids are the worlds of Minecraft. And put that code, before your
And in the final, your MainClass need to be like this.
ModDimensions.class
You can change "test" for the name of your dimension.
TestTeleporter.Class
Use Ctrl+F and search for Blocks.STONE and change this for your block that you use for make the portal. And too, change ModBlocks.customBlock for your portal block, we still need to create him.
And here, is the TileEntity
Case, you changed the name of your Teleporter, use Ctrl+F and search for TestTeleporter, and change this for the name of your class Teleporter.
And before i forget, you have to register your entity, go to your MainClass, and put this
In the "public void init..." method.
For making a dimension, you will need, a Teleporter, ChunkGenerator, WorldProvider, and other little things.
The Chunk is what the world is bascially. For example, i will put my Chunk and World provider here.
TestChunkGenerator.class
Here a NormalTerrainGenerator.
These three compose the world. And will go to generate a world like the Overworld of minecraft. With all that things, your dimension is ready to enter. But now, you need a method for enter. You can make other things instead of an portal, but, in this thread i will go explain how to make the portal.
For make the portal works, we need a custom fire, a custom flint and steel, a custom portal block, and if you want some block that you created for making the structure of portal. First, let's create the portal.
This class is the my custom block portal.
Use Ctrl+F and search for CustomBlock, and change this for the name of your class. And search for ModBlocks.customBlock and change it to the register that you make in the class ModBlocks (if you following other tutorials in this forum, you are understanding me, but, case you have any doubt, ask me). And your ModBlocks class, these blocks we are creating, they don't need a different type of register, they are like this "customBlock = register(new CustomBlock("customBlock", CreativeTabs.REDSTONE));" for example. Before i forget, you need too search for ModBlocks.testFire and change it for the register that you maked in ModBlocks for your custom fire, example: "ModBlocks.customFire". And too, change "Blocks.STONE" to the block what you want to make the portal.
And now, you need to create the custom fire.
Again, use Ctrl+F and search for ModBlocks.customBlock and change it for the block you create a few minutes ago, but, of course, subtitute ModBlocks.customBlock for "ModBlocks.yourblockhere".
And for last, we need to create the flint for put fire in things.
This my custom flint class.
It's very easy to configure this block, use Ctrl+F search for "ModBlocks.testFire" and change it to your register of the block fire you created, example: "ModBlocks.customFire", remember, put the methods of register render for making the texture of items and blocks appears, you need to know how to create blocks and items. If you are following the other tutorials in this forum, you already know this.
That's all. My tutorial is finished here. Sorry my bad English, i already explained my reason for it. Maybe i will create a new tutorial about crops, or something like that... Bye.
I am getting a nullPointerException. Any reason why? I have practically the same code as you.
http://pastebin.com/jCt0ez4B
There is my crash log. Anything else you would like to look at I will provide.
If you would like to get a hold of me somehow, then my discord is @Alex Couch#5275.
Could you paste your LythrmTeleporter file on here? NullPointerException means that you're referencing to a variable that has no assigned value. I don't see what Teleporter.<init> is referring to, but if you could track what value is being used to carry over from TileEntityTele.tele to LythrmTeleporter.<init>, it will probably tell you what is wrong. I don't know what is exactly wrong because I don't have the last 5 lines of the stacktrace and don't know your program.
I would recommend that instead of hard coding the id, you instead use DimensionManager.getNextFreeDimId(), as that will prevent two different mods using the same dimension id. I would also recommend setting all references to the dimension id to the dimension id variable.