Jump to content

Recommended Posts

Posted

How do you teleport the player from the Nether to Overworld without forming a portal?  Entity#travelToDimension and by association ServerConfigurationManager#transferEntityToWorld use Teleporter#placeinPortal, and I'm not sure how to get a valid reference to EntityPlayerMP for ServerConfigurationManager#transferPlayerToDimension.

Posted

First you check if the current player is an instance of EntityPlayerMP, which they will be if the code is executing on the server, and then cast it. You want to use #transferPlayerToDimension with a custom Teleporter that overrides makePortal to do nothing:

((EntityPlayerMP) player).mcServer.getConfigurationManager().transferPlayerToDimension((EntityPlayerMP) player, 0, new TeleporterNoPortal((WorldServer) player.worldObj));

Be sure to adjust the player's posY afterwards or risk falling through the void. I think this may have to do with the chunk not being properly loaded until getBlock is called, which I don't do until adjusting the Y whereas the original has to build the portal... anyway, it works pretty well for my uses.

  • 2 weeks later...
Posted

Ok I can't figure this out, there's a couple problems here, most related to the thread topic: the teleportation works, but it spawns me inside the Nether portal closest to the bed, it seems.  Next, if the player has 2 of the items that trigger this whole event, it takes both of them out of your inventory, and if the player lags on the teleportation, it takes more; I got it to take up to 8 out of the player's inventory in testing.

 

 

 

 

Inventory Watcher

Packet

IEEP

Posted

Why are you sending a packet at all? PlayerTickEvent happens on both sides, so run your teleportation code directly on the server instead of messing with packets. Furthermore, if you are worried about it processing more than once, then set a flag while it is processing to prevent it from resending, but this will not be a problem if you process directly on the server as suggested.

 

As for your teleporter putting you in the nearest portal, that's because that's what it does unless you override more methods like I did in my code, specifically #placeInPortal. I suggest you take a closer look at the vanilla teleporter code.

Posted

Oookay...not sure why I thought I would need a packet, but after putting that stuff in the tick event and overriding the placeInPortal methods, when the teleportion is in the packet it spawns me at my bed, when in the tick event, it spawns me in the middle of some random ocean 300ish blocks away from my bed or world spawn :S

 

 

//Safeguard Talisman
if(player.dimension == -1 && !props.isInNether())
{
props.setInNether(true);
}
if(player.dimension != -1 && props.isInNether())
{
props.setInNether(false);
}
if(props.isInNether())
{
if(player.inventory.hasItem(AAItems.safeguardTalisman))
{
	if(player.worldObj.getBlock((int)player.posX, (int)player.posY, (int)player.posZ).equals(Blocks.lava) || player.worldObj.getBlock((int)player.posX, (int)player.posY, (int)player.posZ).equals(Blocks.flowing_lava) || player.isBurning())
	{
		if(event.side == Side.SERVER)
		{
			if(player instanceof EntityPlayerMP)
			{
				EntityPlayerMP playerMP = (EntityPlayerMP)player;
				for (int i = 0; i < playerMP.inventory.mainInventory.length - 4; ++i)
				{
					if (playerMP.inventory.mainInventory[i] != null && playerMP.inventory.mainInventory[i].getItem() == AAItems.safeguardTalisman)
					{
						playerMP.inventory.mainInventory[i] = null;
						break;
					}
				}

				playerMP.mcServer.getConfigurationManager().transferPlayerToDimension(playerMP, 0, new TeleporterNP(playerMP.mcServer.worldServerForDimension(0)));
				ChunkCoordinates bed = playerMP.getBedLocation(0);
				if(bed != null)
				{
					bed.posY = playerMP.worldObj.getTopSolidOrLiquidBlock(bed.posX, bed.posZ);
					playerMP.setLocationAndAngles(bed.posX, bed.posY, bed.posZ, playerMP.rotationYaw, playerMP.rotationPitch);
				}
				else
				{
					ChunkCoordinates spawn = playerMP.worldObj.getSpawnPoint();
					spawn.posY = playerMP.worldObj.getTopSolidOrLiquidBlock(spawn.posX, spawn.posZ);
					playerMP.setLocationAndAngles(spawn.posX, spawn.posY, spawn.posZ, playerMP.rotationYaw, playerMP.rotationPitch);
				}
				playerMP.fallDistance = 0.0f;
			}
		}
		props.setInNether(false);
	}
}
}

Posted

This has been happening with teleporting into my dimension too, the coordinates you spawn at don't match the coordinates given to the setLocationAndAngles.

 

 

Yeah, I printed the coordinates, they're both the same: the player's bed, only the packet actually spawns you at the right location.  You typically spawn deep underground in a wall, or way up in the air with the teleportation inside the tick event, and always within 200 blocks of the printed coordinates, on the x and z axes.

 

 

Splitting it to do the teleportation in the packet and the removing of the item from the inventory in the tick event doesn't work either, it teleports to the right location, and takes multiple items. Aaaaand the mystery deepens, I just got one time where it took none of the item, and the next, it took 4.

 

 

Tick Event

Packet

Teleporter

Posted

Ok, I moved the positioning to the teleporter, and I fixed the item removal by using IEEP with the dimension change event, but there's still one issue, even if you break your bed, you still teleport to its location instead of world spawn.

 

 

 

public class OverworldTeleporterNP extends Teleporter
{
final WorldServer worldServer;


public OverworldTeleporterNP(WorldServer worldServer)
{
	super(worldServer);
	this.worldServer = worldServer;
}


@Override
public boolean makePortal(Entity entity){return true;}


@Override
public void placeInPortal(Entity entity, double x, double y, double z, float yaw)
{
	if(entity instanceof EntityPlayer)
	{
		EntityPlayer player = (EntityPlayer)entity;
		ChunkCoordinates bed = player.getBedLocation(0);
		if(bed != null)
		{
			bed.posY = player.worldObj.getTopSolidOrLiquidBlock(bed.posX, bed.posZ);
			player.setPositionAndUpdate(bed.posX, bed.posY + 1, bed.posZ);
		}
		else
		{
			ChunkCoordinates spawn = player.worldObj.getSpawnPoint();
			spawn.posY = player.worldObj.getTopSolidOrLiquidBlock(spawn.posX, spawn.posZ);
			player.setPositionAndUpdate(spawn.posX, spawn.posY + 1, spawn.posZ);


		}
	}
}
}

Posted

Vanilla almost ALWAYS has the answers.

 

I know it can be hard to find things sometimes in the vanilla code, but you should at least try. In this case, the answer lies in ServerConfigurationManager#respawnPlayer, which uses 'verifyRespawnCoordinates' to check if the bed is still valid, and below is code that I have adapted from that for my own use:

ChunkCoordinates cc = player.getBedLocation(player.dimension);
if (cc != null) {
cc = EntityPlayer.verifyRespawnCoordinates(player.worldObj, cc, player.isSpawnForced(player.dimension));
}
if (cc == null) {
cc = player.worldObj.getSpawnPoint();
}
if (cc != null) {
  // now you have the correct spawn coordinates
}

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.