Modding 1.4.7: Custom Dimension Part 5: Teleporter

In this tutorial I will show you how to create a Teleporter file. This is a pretty important file.
When you place a portal in the dimension you are in, this file will make sure that it either places a tutorial at a valid location, or it will get you in an already existing portal.
This is the portal block file I will start with.


package tutorial;

import java.util.Random;

import net.minecraft.block.Block;
import net.minecraft.block.BlockPortal;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.world.World;

public class BlockPortalTutorial extends BlockPortal
{
public BlockPortalTutorial(int id, int texture)
{
super(id, texture);
this.setCreativeTab(CreativeTabs.tabBlock);
}

public String getTextureFile()
    {
            return “/tutorialblocks.png”;
    }

public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
{

}

public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity)
{
if (par5Entity.ridingEntity == null && par5Entity.riddenByEntity == null)
{
if (par5Entity instanceof EntityPlayerMP)
{
EntityPlayerMP thePlayer = (EntityPlayerMP) par5Entity;
if (par5Entity.dimension != Tutorial.dimension)
{
thePlayer.mcServer.getConfigurationManager().transferPlayerToDimension(thePlayer, Tutorial.dimension, new TeleporterTutorial(thePlayer.mcServer.worldServerForDimension(Tutorial.dimension)));
}
else
{
thePlayer.mcServer.getConfigurationManager().transferPlayerToDimension(thePlayer, 0, new TeleporterTutorial(thePlayer.mcServer.worldServerForDimension(0)));
}
}
}
}

public boolean tryToCreatePortal(World par1World, int par2, int par3, int par4)
    {
        byte var5 = 0;
        byte var6 = 0;

        if (par1World.getBlockId(par2 – 1, par3, par4) == Block.sandStone.blockID || par1World.getBlockId(par2 + 1, par3, par4) == Block.sandStone.blockID)
        {
            var5 = 1;
        }

        if (par1World.getBlockId(par2, par3, par4 – 1) == Block.sandStone.blockID || par1World.getBlockId(par2, par3, par4 + 1) == Block.sandStone.blockID)
        {
            var6 = 1;
        }

        if (var5 == var6)
        {
            return false;
        }
        else
        {
            if (par1World.getBlockId(par2 – var5, par3, par4 – var6) == 0)
            {
                par2 -= var5;
                par4 -= var6;
            }

            int var7;
            int var8;

            for (var7 = -1; var7 <= 2; ++var7)
            {
                for (var8 = -1; var8 <= 3; ++var8)
                {
                    boolean var9 = var7 == -1 || var7 == 2 || var8 == -1 || var8 == 3;

                    if (var7 != -1 && var7 != 2 || var8 != -1 && var8 != 3)
                    {
                        int var10 = par1World.getBlockId(par2 + var5 * var7, par3 + var8, par4 + var6 * var7);

                        if (var9)
                        {
                            if (var10 != Block.sandStone.blockID)
                            {
                                return false;
                            }
                        }
                        else if (var10 != 0 && var10 != Block.fire.blockID)
                        {
                            return false;
                        }
                    }
                }
            }

            par1World.editingBlocks = true;

            for (var7 = 0; var7 < 2; ++var7)
            {
                for (var8 = 0; var8 < 3; ++var8)
                {
                    par1World.setBlockWithNotify(par2 + var5 * var7, par3 + var8, par4 + var6 * var7, this.blockID);
                }
            }

            par1World.editingBlocks = false;
            return true;
        }
    }

public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random)
    {
        
    }

public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
{
byte var6 = 0;
byte var7 = 1;

if (par1World.getBlockId(par2 – 1, par3, par4) == this.blockID || par1World.getBlockId(par2 + 1, par3, par4) == this.blockID)
{
var6 = 1;
var7 = 0;
}

int var8;

for (var8 = par3; par1World.getBlockId(par2, var8 – 1, par4) == this.blockID; –var8)
{
;
}

if (par1World.getBlockId(par2, var8 – 1, par4) != Block.sandStone.blockID)
{
par1World.setBlockWithNotify(par2, par3, par4, 0);
}
else
{
int var9;

for (var9 = 1; var9 < 4 && par1World.getBlockId(par2, var8 + var9, par4) == this.blockID; ++var9)
{
;
}

if (var9 == 3 && par1World.getBlockId(par2, var8 + var9, par4) == Block.sandStone.blockID)
{
boolean var10 = par1World.getBlockId(par2 – 1, par3, par4) == this.blockID || par1World.getBlockId(par2 + 1, par3, par4) == this.blockID;
boolean var11 = par1World.getBlockId(par2, par3, par4 – 1) == this.blockID || par1World.getBlockId(par2, par3, par4 + 1) == this.blockID;

if (var10 && var11)
{
par1World.setBlockWithNotify(par2, par3, par4, 0);
}
else
{
if ((par1World.getBlockId(par2 + var6, par3, par4 + var7) != Block.sandStone.blockID || par1World.getBlockId(par2 – var6, par3, par4 – var7) != this.blockID) && (par1World.getBlockId(par2 – var6, par3, par4 – var7) != Block.sandStone.blockID || par1World.getBlockId(par2 + var6, par3, par4 + var7) != this.blockID))
{
par1World.setBlockWithNotify(par2, par3, par4, 0);
}
}
}
else
{
par1World.setBlockWithNotify(par2, par3, par4, 0);
}
}
}
}


In this file there should be 2 errors under the Teleporter files. To fix that you have to hover your mouse over it and create the file. Now you should copy the following code and paste it in there.


package tutorial;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.util.Direction;
import net.minecraft.util.LongHashMap;
import net.minecraft.util.MathHelper;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.PortalPosition;
import net.minecraft.world.Teleporter;
import net.minecraft.world.WorldServer;

public class TeleporterTutorial extends Teleporter
{
private final WorldServer field_85192_a;
private final Random random;
private final LongHashMap field_85191_c = new LongHashMap();
private final List field_85190_d = new ArrayList();

public TeleporterTutorial(WorldServer par1WorldServer)
{
super(par1WorldServer);
this.field_85192_a = par1WorldServer;
this.random = new Random(par1WorldServer.getSeed());
}

@Override
public void placeInPortal(Entity par1Entity, double par2, double par4, double par6, float par8)
{
if (this.field_85192_a.provider.dimensionId != 1)
{
if (!this.placeInExistingPortal(par1Entity, par2, par4, par6, par8))
{
this.func_85188_a(par1Entity);
this.placeInExistingPortal(par1Entity, par2, par4, par6, par8);
}
}
else
{
int var9 = MathHelper.floor_double(par1Entity.posX);
int var10 = MathHelper.floor_double(par1Entity.posY) – 1;
int var11 = MathHelper.floor_double(par1Entity.posZ);
byte var12 = 1;
byte var13 = 0;

for (int var14 = -2; var14 <= 2; ++var14)
{
for (int var15 = -2; var15 <= 2; ++var15)
{
for (int var16 = -1; var16 < 3; ++var16)
{
int var17 = var9 + var15 * var12 + var14 * var13;
int var18 = var10 + var16;
int var19 = var11 + var15 * var13 – var14 * var12;
boolean var20 = var16 < 0;
this.field_85192_a.setBlockWithNotify(var17, var18, var19, var20 ? Block.sandStone.blockID : 0);
}
}
}

par1Entity.setLocationAndAngles((double) var9, (double) var10, (double) var11, par1Entity.rotationYaw, 0.0F);
par1Entity.motionX = par1Entity.motionY = par1Entity.motionZ = 0.0D;
}
}

@Override
public boolean placeInExistingPortal(Entity par1Entity, double par2, double par4, double par6, float par8)
{
short var9 = 128;
double var10 = -1.0D;
int var12 = 0;
int var13 = 0;
int var14 = 0;
int var15 = MathHelper.floor_double(par1Entity.posX);
int var16 = MathHelper.floor_double(par1Entity.posZ);
long var17 = ChunkCoordIntPair.chunkXZ2Int(var15, var16);
boolean var19 = true;
double var27;
int var48;

if (this.field_85191_c.containsItem(var17))
{
PortalPosition var20 = (PortalPosition) this.field_85191_c.getValueByKey(var17);
var10 = 0.0D;
var12 = var20.posX;
var13 = var20.posY;
var14 = var20.posZ;
var20.field_85087_d = this.field_85192_a.getTotalWorldTime();
var19 = false;
}
else
{
for (var48 = var15 – var9; var48 <= var15 + var9; ++var48)
{
double var21 = (double) var48 + 0.5D – par1Entity.posX;

for (int var23 = var16 – var9; var23 <= var16 + var9; ++var23)
{
double var24 = (double) var23 + 0.5D – par1Entity.posZ;

for (int var26 = this.field_85192_a.getActualHeight() – 1; var26 >= 0; –var26)
{
if (this.field_85192_a.getBlockId(var48, var26, var23) == Tutorial.portal.blockID)
{
while (this.field_85192_a.getBlockId(var48, var26 – 1, var23) == Tutorial.portal.blockID)
{
–var26;
}

var27 = (double) var26 + 0.5D – par1Entity.posY;
double var29 = var21 * var21 + var27 * var27 + var24 * var24;

if (var10 < 0.0D || var29 < var10)
{
var10 = var29;
var12 = var48;
var13 = var26;
var14 = var23;
}
}
}
}
}
}

if (var10 >= 0.0D)
{
if (var19)
{
this.field_85191_c.add(var17, new PortalPosition(this, var12, var13, var14, this.field_85192_a.getTotalWorldTime()));
this.field_85190_d.add(Long.valueOf(var17));
}

double var49 = (double) var12 + 0.5D;
double var25 = (double) var13 + 0.5D;
var27 = (double) var14 + 0.5D;
int var50 = -1;

if (this.field_85192_a.getBlockId(var12 – 1, var13, var14) == Tutorial.portal.blockID)
{
var50 = 2;
}

if (this.field_85192_a.getBlockId(var12 + 1, var13, var14) == Tutorial.portal.blockID)
{
var50 = 0;
}

if (this.field_85192_a.getBlockId(var12, var13, var14 – 1) == Tutorial.portal.blockID)
{
var50 = 3;
}

if (this.field_85192_a.getBlockId(var12, var13, var14 + 1) == Tutorial.portal.blockID)
{
var50 = 1;
}

int var30 = par1Entity.func_82148_at();

if (var50 > -1)
{
int var31 = Direction.field_71578_g[var50];
int var32 = Direction.offsetX[var50];
int var33 = Direction.offsetZ[var50];
int var34 = Direction.offsetX[var31];
int var35 = Direction.offsetZ[var31];
boolean var36 = !this.field_85192_a.isAirBlock(var12 + var32 + var34, var13, var14 + var33 + var35) || !this.field_85192_a.isAirBlock(var12 + var32 + var34, var13 + 1, var14 + var33 + var35);
boolean var37 = !this.field_85192_a.isAirBlock(var12 + var32, var13, var14 + var33) || !this.field_85192_a.isAirBlock(var12 + var32, var13 + 1, var14 + var33);

if (var36 && var37)
{
var50 = Direction.footInvisibleFaceRemap[var50];
var31 = Direction.footInvisibleFaceRemap[var31];
var32 = Direction.offsetX[var50];
var33 = Direction.offsetZ[var50];
var34 = Direction.offsetX[var31];
var35 = Direction.offsetZ[var31];
var48 = var12 – var34;
var49 -= (double) var34;
int var22 = var14 – var35;
var27 -= (double) var35;
var36 = !this.field_85192_a.isAirBlock(var48 + var32 + var34, var13, var22 + var33 + var35) || !this.field_85192_a.isAirBlock(var48 + var32 + var34, var13 + 1, var22 + var33 + var35);
var37 = !this.field_85192_a.isAirBlock(var48 + var32, var13, var22 + var33) || !this.field_85192_a.isAirBlock(var48 + var32, var13 + 1, var22 + var33);
}

float var38 = 0.5F;
float var39 = 0.5F;

if (!var36 && var37)
{
var38 = 1.0F;
}
else if (var36 && !var37)
{
var38 = 0.0F;
}
else if (var36 && var37)
{
var39 = 0.0F;
}

var49 += (double) ((float) var34 * var38 + var39 * (float) var32);
var27 += (double) ((float) var35 * var38 + var39 * (float) var33);
float var40 = 0.0F;
float var41 = 0.0F;
float var42 = 0.0F;
float var43 = 0.0F;

if (var50 == var30)
{
var40 = 1.0F;
var41 = 1.0F;
}
else if (var50 == Direction.footInvisibleFaceRemap[var30])
{
var40 = -1.0F;
var41 = -1.0F;
}
else if (var50 == Direction.enderEyeMetaToDirection[var30])
{
var42 = 1.0F;
var43 = -1.0F;
}
else
{
var42 = -1.0F;
var43 = 1.0F;
}

double var44 = par1Entity.motionX;
double var46 = par1Entity.motionZ;
par1Entity.motionX = var44 * (double) var40 + var46 * (double) var43;
par1Entity.motionZ = var44 * (double) var42 + var46 * (double) var41;
par1Entity.rotationYaw = par8 – (float) (var30 * 90) + (float) (var50 * 90);
}
else
{
par1Entity.motionX = par1Entity.motionY = par1Entity.motionZ = 0.0D;
}

par1Entity.setLocationAndAngles(var49 + 3, var25, var27 + 3, par1Entity.rotationYaw, par1Entity.rotationPitch);
return true;
}
else
{
return false;
}
}

@Override
public boolean func_85188_a(Entity par1Entity)
{
byte var2 = 16;
double var3 = -1.0D;
int var5 = MathHelper.floor_double(par1Entity.posX);
int var6 = MathHelper.floor_double(par1Entity.posY);
int var7 = MathHelper.floor_double(par1Entity.posZ);
int var8 = var5;
int var9 = var6;
int var10 = var7;
int var11 = 0;
int var12 = this.random.nextInt(4);
int var13;
double var14;
double var17;
int var16;
int var19;
int var21;
int var20;
int var23;
int var22;
int var25;
int var24;
int var27;
int var26;
double var31;
double var32;

for (var13 = var5 – var2; var13 <= var5 + var2; ++var13)
{
var14 = (double) var13 + 0.5D – par1Entity.posX;

for (var16 = var7 – var2; var16 <= var7 + var2; ++var16)
{
var17 = (double) var16 + 0.5D – par1Entity.posZ;
label274:

for (var19 = this.field_85192_a.getActualHeight() – 1; var19 >= 0; –var19)
{
if (this.field_85192_a.isAirBlock(var13, var19, var16))
{
while (var19 > 0 && this.field_85192_a.isAirBlock(var13, var19 – 1, var16))
{
–var19;
}

for (var20 = var12; var20 < var12 + 4; ++var20)
{
var21 = var20 % 2;
var22 = 1 – var21;

if (var20 % 4 >= 2)
{
var21 = -var21;
var22 = -var22;
}

for (var23 = 0; var23 < 3; ++var23)
{
for (var24 = 0; var24 < 4; ++var24)
{
for (var25 = -1; var25 < 4; ++var25)
{
var26 = var13 + (var24 – 1) * var21 + var23 * var22;
var27 = var19 + var25;
int var28 = var16 + (var24 – 1) * var22 – var23 * var21;

if (var25 < 0 && !this.field_85192_a.getBlockMaterial(var26, var27, var28).isSolid() || var25 >= 0 && !this.field_85192_a.isAirBlock(var26, var27, var28))
{
continue label274;
}
}
}
}

var32 = (double) var19 + 0.5D – par1Entity.posY;
var31 = var14 * var14 + var32 * var32 + var17 * var17;

if (var3 < 0.0D || var31 < var3)
{
var3 = var31;
var8 = var13;
var9 = var19;
var10 = var16;
var11 = var20 % 4;
}
}
}
}
}
}

if (var3 < 0.0D)
{
for (var13 = var5 – var2; var13 <= var5 + var2; ++var13)
{
var14 = (double) var13 + 0.5D – par1Entity.posX;

for (var16 = var7 – var2; var16 <= var7 + var2; ++var16)
{
var17 = (double) var16 + 0.5D – par1Entity.posZ;
label222:

for (var19 = this.field_85192_a.getActualHeight() – 1; var19 >= 0; –var19)
{
if (this.field_85192_a.isAirBlock(var13, var19, var16))
{
while (var19 > 0 && this.field_85192_a.isAirBlock(var13, var19 – 1, var16))
{
–var19;
}

for (var20 = var12; var20 < var12 + 2; ++var20)
{
var21 = var20 % 2;
var22 = 1 – var21;

for (var23 = 0; var23 < 4; ++var23)
{
for (var24 = -1; var24 < 4; ++var24)
{
var25 = var13 + (var23 – 1) * var21;
var26 = var19 + var24;
var27 = var16 + (var23 – 1) * var22;

if (var24 < 0 && !this.field_85192_a.getBlockMaterial(var25, var26, var27).isSolid() || var24 >= 0 && !this.field_85192_a.isAirBlock(var25, var26, var27))
{
continue label222;
}
}
}

var32 = (double) var19 + 0.5D – par1Entity.posY;
var31 = var14 * var14 + var32 * var32 + var17 * var17;

if (var3 < 0.0D || var31 < var3)
{
var3 = var31;
var8 = var13;
var9 = var19;
var10 = var16;
var11 = var20 % 2;
}
}
}
}
}
}
}

int var29 = var8;
int var15 = var9;
var16 = var10;
int var30 = var11 % 2;
int var18 = 1 – var30;

if (var11 % 4 >= 2)
{
var30 = -var30;
var18 = -var18;
}

boolean var33;

if (var3 < 0.0D)
{
if (var9 < 70)
{
var9 = 70;
}

if (var9 > this.field_85192_a.getActualHeight() – 10)
{
var9 = this.field_85192_a.getActualHeight() – 10;
}

var15 = var9;

for (var19 = -1; var19 <= 1; ++var19)
{
for (var20 = 1; var20 < 3; ++var20)
{
for (var21 = -1; var21 < 3; ++var21)
{
var22 = var29 + (var20 – 1) * var30 + var19 * var18;
var23 = var15 + var21;
var24 = var16 + (var20 – 1) * var18 – var19 * var30;
var33 = var21 < 0;
this.field_85192_a.setBlockWithNotify(var22, var23, var24, var33 ? Block.sandStone.blockID : 0);
}
}
}
}

for (var19 = 0; var19 < 4; ++var19)
{
this.field_85192_a.editingBlocks = true;

for (var20 = 0; var20 < 4; ++var20)
{
for (var21 = -1; var21 < 4; ++var21)
{
var22 = var29 + (var20 – 1) * var30;
var23 = var15 + var21;
var24 = var16 + (var20 – 1) * var18;
var33 = var20 == 0 || var20 == 3 || var21 == -1 || var21 == 3;
this.field_85192_a.setBlockWithNotify(var22, var23, var24, var33 ? Block.sandStone.blockID : Tutorial.portal.blockID);
}
}

this.field_85192_a.editingBlocks = false;

for (var20 = 0; var20 < 4; ++var20)
{
for (var21 = -1; var21 < 4; ++var21)
{
var22 = var29 + (var20 – 1) * var30;
var23 = var15 + var21;
var24 = var16 + (var20 – 1) * var18;
this.field_85192_a.notifyBlocksOfNeighborChange(var22, var23, var24, this.field_85192_a.getBlockId(var22, var23, var24));
}
}
}

return true;
}

@Override
public void func_85189_a(long par1)
{
if (par1 % 100L == 0L)
{
Iterator var3 = this.field_85190_d.iterator();
long var4 = par1 – 600L;

while (var3.hasNext())
{
Long var6 = (Long) var3.next();
PortalPosition var7 = (PortalPosition) this.field_85191_c.getValueByKey(var6.longValue());

if (var7 == null || var7.field_85087_d < var4)
{
var3.remove();
this.field_85191_c.remove(var6.longValue());
}
}
}
}

}


As you can see this is a lot of complicated code. This is because there is a lot of math behind the placing of a portal.
When you paste this in there there will probably some errors. That is because you don’t have a block called portal in the Tutorial file. To fix this press Ctrl, Shift, F. In the top box typ in Tutorial.portal. In the box below you should add YourModFile.YourPortalBlock. Then click the Replace All button on the bottom and all the errors should go away.
The code I provide right now will make a portal with sandStone blocks. If you want the portal to be made out of other blocks make sure that you search for sandStone and replace it with the block you want just like you did above to fix the portal block errors.
I’m not going to explain all of this code, because it will not only take me hours and hours, but it will also be useless. The only thing you need to worry about is that you select the right portal block and portal frame. All the other work is already done by Mojang (and a tiny bit by me).
One important thing to note is that you might get errors under your method names. If the errors sais something like: The method [methodname] of type YourTeleporterFile must override or implement a supertype method. If this happens you should go to the Teleporter file located in net.minecraft.world. In here you should select the right method and copy it over to your teleporter file. If you need any help with this just leave a message on the forums or email me at wuppy29@gmail.com.

In the next tutorial I will show you how to create your own WorldProvider file.

The source code will be avaliable at the end of the last tutorial.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">