From 2c92a9e0c1d813c6812dac0d6936f6f421187e12 Mon Sep 17 00:00:00 2001 From: AEon - Tobias Date: Wed, 8 Aug 2018 02:50:56 +0200 Subject: [PATCH] Crossdimensional Teleposition (including entities, into unloaded chunks etc) (#1385) * AWAITING ALLOWANCE FROM BRANDON3055 (PERMISSION TO USE CODE SNIPPET FOR INTERDIMENSIONAL/CROSSDIMENSIONAL TELEPORT) COPYRIGHT ALL RIGHTS RESERVED FOR BRANDON3055 (CODE SNIPPET) AWAITING ALLOWANCE FROM TEHNUT, WAYOFTIME TO USE FOREIGN CODE (AS IT NEEDS ALLOWANCE & POSSIBLE CREDITS) DO NOT USE. * Forgot something. Requires permission from Brandon3055 (copyright on code snippet) Requires permission from WayofTime, TehNut (because it uses foreign code that might need attribution) Do not use. * License permits usage. Sorry for bothering everyone involved. Don't merge. Teleposer broken. Teleposition sigil works though. * IT WORKS!!!! - re-enabled cross dimensional telepositioning - works even if target teleposer is unloaded at the time of activation (force loads the chunk so the teleposer can be found, releases ticket when player arrives) - entity teleposition works properly - I'm tired and slightly insane - nobody asked for this. closes #973 (rewrite might still be needed though) might be able to close the following issue: - #1198 (improved cross dimensional teleportation code thanks to brandon3055) * Zombies stop holding onto tickets now. * Oversight. --- .../item/sigil/ItemSigilTeleposition.java | 14 +-- .../bloodmagic/ritual/portal/Teleports.java | 85 ++++++++++++++----- .../bloodmagic/tile/TileTeleposer.java | 34 ++++---- 3 files changed, 90 insertions(+), 43 deletions(-) diff --git a/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilTeleposition.java b/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilTeleposition.java index 10e44dab..ebca00db 100644 --- a/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilTeleposition.java +++ b/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilTeleposition.java @@ -26,6 +26,7 @@ import net.minecraftforge.fml.relauncher.SideOnly; import javax.annotation.Nullable; import java.util.List; +import java.util.UUID; public class ItemSigilTeleposition extends ItemSigilBase { @@ -62,16 +63,17 @@ public class ItemSigilTeleposition extends ItemSigilBase { TileEntity tile = teleportTo.getTileEntity(location.pos); if (tile instanceof TileTeleposer) { BlockPos blockPos = location.pos.up(); + UUID bindingOwnerID = binding.getOwnerId(); if (world.provider.getDimension() == location.dim) { - TeleportQueue.getInstance().addITeleport(new Teleports.TeleportSameDim(blockPos, player, binding.getOwnerId(), true)); + TeleportQueue.getInstance().addITeleport(new Teleports.TeleportSameDim(blockPos, player, bindingOwnerID, true)); + + } else { + TeleportQueue.getInstance().addITeleport(new Teleports.TeleportToDim(blockPos, player, bindingOwnerID, world, tile.getWorld().provider.getDimension(), true)); } - // FIXME - Fix cross-dimension teleports causing major desync -// } else { -// TeleportQueue.getInstance().addITeleport(new Teleports.TeleportToDim(blockPos, player, getOwnerUUID(stack), world, getValue(stack.getTagCompound(), Constants.NBT.DIMENSION_ID), true)); -// } + } } } - } + return super.onItemRightClick(world, player, hand); } diff --git a/src/main/java/WayofTime/bloodmagic/ritual/portal/Teleports.java b/src/main/java/WayofTime/bloodmagic/ritual/portal/Teleports.java index 79902bc7..5f253ca1 100644 --- a/src/main/java/WayofTime/bloodmagic/ritual/portal/Teleports.java +++ b/src/main/java/WayofTime/bloodmagic/ritual/portal/Teleports.java @@ -1,6 +1,7 @@ package WayofTime.bloodmagic.ritual.portal; import WayofTime.bloodmagic.core.data.SoulNetwork; + import WayofTime.bloodmagic.core.data.SoulTicket; import WayofTime.bloodmagic.event.TeleposeEvent; import WayofTime.bloodmagic.teleport.Teleport; @@ -10,13 +11,20 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.SoundEvents; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.play.server.SPacketEntityEffect; +import net.minecraft.network.play.server.SPacketPlayerAbilities; +import net.minecraft.network.play.server.SPacketRespawn; import net.minecraft.network.play.server.SPacketUpdateHealth; +import net.minecraft.potion.PotionEffect; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.management.PlayerList; import net.minecraft.util.SoundCategory; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; import net.minecraft.util.text.TextComponentString; import net.minecraft.world.World; import net.minecraft.world.WorldServer; +import net.minecraftforge.common.ForgeChunkManager; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.FMLCommonHandler; @@ -39,15 +47,16 @@ public class Teleports { @Override public void teleport() { if (entity != null) { + BlockPos targetTeleposer = new BlockPos(x,y,z); if (entity.timeUntilPortal <= 0) { if (entity instanceof EntityPlayer) { + SoulNetwork network = NetworkHelper.getSoulNetwork(networkOwner); if (network.getCurrentEssence() < getTeleportCost()) return; - if (teleposer) - if (MinecraftForge.EVENT_BUS.post(new TeleposeEvent.Ent(entity, entity.getEntityWorld(), entity.getPosition(), entity.getEntityWorld(), new BlockPos(x, y, z)))) - return; + if (teleposer && MinecraftForge.EVENT_BUS.post(new TeleposeEvent.Ent(entity, entity.getEntityWorld(), entity.getPosition(), entity.getEntityWorld(), targetTeleposer))) + return; EntityPlayerMP player = (EntityPlayerMP) entity; @@ -60,15 +69,14 @@ public class Teleports { player.getEntityWorld().playSound(x, y, z, SoundEvents.ENTITY_ENDERMEN_TELEPORT, SoundCategory.AMBIENT, 1.0F, 1.0F, false); if (teleposer) - MinecraftForge.EVENT_BUS.post(new TeleposeEvent.Ent.Post(entity, entity.getEntityWorld(), entity.getPosition(), entity.getEntityWorld(), new BlockPos(x, y, z))); + MinecraftForge.EVENT_BUS.post(new TeleposeEvent.Ent.Post(entity, entity.getEntityWorld(), entity.getPosition(), entity.getEntityWorld(), targetTeleposer)); } else { SoulNetwork network = NetworkHelper.getSoulNetwork(networkOwner); if (network.getCurrentEssence() < (getTeleportCost() / 10)) return; - if (teleposer) - if (MinecraftForge.EVENT_BUS.post(new TeleposeEvent.Ent(entity, entity.getEntityWorld(), entity.getPosition(), entity.getEntityWorld(), new BlockPos(x, y, z)))) - return; + if (teleposer && MinecraftForge.EVENT_BUS.post(new TeleposeEvent.Ent(entity, entity.getEntityWorld(), entity.getPosition(), entity.getEntityWorld(), targetTeleposer))) + return; WorldServer world = (WorldServer) entity.getEntityWorld(); @@ -80,7 +88,7 @@ public class Teleports { entity.getEntityWorld().playSound(x, y, z, SoundEvents.ENTITY_ENDERMEN_TELEPORT, SoundCategory.AMBIENT, 1.0F, 1.0F, false); if (teleposer) - MinecraftForge.EVENT_BUS.post(new TeleposeEvent.Ent.Post(entity, entity.getEntityWorld(), entity.getPosition(), entity.getEntityWorld(), new BlockPos(x, y, z))); + MinecraftForge.EVENT_BUS.post(new TeleposeEvent.Ent.Post(entity, entity.getEntityWorld(), entity.getPosition(), entity.getEntityWorld(), targetTeleposer)); } } } @@ -115,28 +123,65 @@ public class Teleports { MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance(); WorldServer oldWorldServer = server.getWorld(entity.dimension); WorldServer newWorldServer = server.getWorld(newWorldID); + BlockPos targetTeleposer = new BlockPos(x,y,z); + ChunkPos teleposerChunk = new ChunkPos(targetTeleposer); + ForgeChunkManager.Ticket chunkTicket = ForgeChunkManager.requestTicket("bloodmagic", newWorldServer, ForgeChunkManager.Type.NORMAL); + ForgeChunkManager.forceChunk(chunkTicket ,teleposerChunk); if (entity instanceof EntityPlayer) { EntityPlayerMP player = (EntityPlayerMP) entity; + if (!player.getEntityWorld().isRemote) { SoulNetwork network = NetworkHelper.getSoulNetwork(networkOwner); if (network.getCurrentEssence() < getTeleportCost()) return; - if (teleposer) - if (MinecraftForge.EVENT_BUS.post(new TeleposeEvent.Ent(entity, entity.getEntityWorld(), entity.getPosition(), newWorldServer, new BlockPos(x, y, z)))) + if (teleposer && MinecraftForge.EVENT_BUS.post(new TeleposeEvent.Ent(entity, entity.getEntityWorld(), entity.getPosition(), newWorldServer, targetTeleposer))) return; network.syphon(ticket(oldWorld, player, getTeleportCost())); - player.changeDimension(newWorldID); //TODO: UNTESTED -// server.getConfigurationManager().transferPlayerToDimension(player, newWorldID, new TeleporterBloodMagic(newWorldServer)); - player.setPositionAndUpdate(x + 0.5, y + 0.5, z + 0.5); - player.getEntityWorld().updateEntityWithOptionalForce(player, false); - player.connection.sendPacket(new SPacketUpdateHealth(player.getHealth(), player.getFoodStats().getFoodLevel(), player.getFoodStats().getSaturationLevel())); + + + /* begin brandon3055 "BrandonsCore" intedimensional teleportation code */ + + PlayerList playerList = server.getPlayerList(); + + player.dimension = newWorldID; + player.connection.sendPacket(new SPacketRespawn(player.dimension, newWorldServer.getDifficulty(), newWorldServer.getWorldInfo().getTerrainType(), player.interactionManager.getGameType())); + playerList.updatePermissionLevel(player); + oldWorldServer.removeEntityDangerously(player); + player.isDead = false; + + //region Transfer to world + + player.setLocationAndAngles(x + 0.5, y + 0.5, z + 0.5, player.rotationYaw, player.rotationPitch); + player.connection.setPlayerLocation(x + 0.5, y + 0.5, z + 0.5, player.rotationYaw, player.rotationPitch); + newWorldServer.spawnEntity(player); + newWorldServer.updateEntityWithOptionalForce(player, false); + player.setWorld(newWorldServer); + + //endregion + + playerList.preparePlayer(player, oldWorldServer); + player.connection.setPlayerLocation(x + 0.5, y + 0.5, z + 0.5, player.rotationYaw, player.rotationPitch); + player.interactionManager.setWorld(newWorldServer); + player.connection.sendPacket(new SPacketPlayerAbilities(player.capabilities)); + + playerList.updateTimeAndWeatherForPlayer(player, newWorldServer); + playerList.syncPlayerInventory(player); + + for (PotionEffect potioneffect : player.getActivePotionEffects()) { + player.connection.sendPacket(new SPacketEntityEffect(player.getEntityId(), potioneffect)); + } + FMLCommonHandler.instance().firePlayerChangedDimensionEvent(player, entity.dimension, newWorldID); + player.setLocationAndAngles(x + 0.5, y + 0.5, z + 0.5, player.rotationYaw, player.rotationPitch); + + /* end brandon3055 teleportation code */ + if (teleposer) - MinecraftForge.EVENT_BUS.post(new TeleposeEvent.Ent.Post(entity, entity.getEntityWorld(), entity.getPosition(), newWorldServer, new BlockPos(x, y, z))); + MinecraftForge.EVENT_BUS.post(new TeleposeEvent.Ent.Post(entity, entity.getEntityWorld(), entity.getPosition(), newWorldServer, targetTeleposer)); } } else if (!entity.getEntityWorld().isRemote) { @@ -144,9 +189,8 @@ public class Teleports { if (network.getCurrentEssence() < (getTeleportCost() / 10)) return; - if (teleposer) - if (MinecraftForge.EVENT_BUS.post(new TeleposeEvent.Ent(entity, entity.getEntityWorld(), entity.getPosition(), newWorldServer, new BlockPos(x, y, z)))) - return; + if (teleposer && MinecraftForge.EVENT_BUS.post(new TeleposeEvent.Ent(entity, entity.getEntityWorld(), entity.getPosition(), newWorldServer, targetTeleposer))) + return; network.syphon(ticket(oldWorld, entity, getTeleportCost() / 10)); @@ -168,10 +212,11 @@ public class Teleports { oldWorldServer.resetUpdateEntityTick(); newWorldServer.resetUpdateEntityTick(); if (teleposer) - MinecraftForge.EVENT_BUS.post(new TeleposeEvent.Ent.Post(entity, entity.getEntityWorld(), entity.getPosition(), newWorldServer, new BlockPos(x, y, z))); + MinecraftForge.EVENT_BUS.post(new TeleposeEvent.Ent.Post(entity, entity.getEntityWorld(), entity.getPosition(), newWorldServer, targetTeleposer)); } entity.timeUntilPortal = entity instanceof EntityLiving ? 150 : 20; newWorldServer.playSound(x, y, z, SoundEvents.ENTITY_ENDERMEN_TELEPORT, SoundCategory.AMBIENT, 1.0F, 1.0F, false); + ForgeChunkManager.releaseTicket(chunkTicket); } } } diff --git a/src/main/java/WayofTime/bloodmagic/tile/TileTeleposer.java b/src/main/java/WayofTime/bloodmagic/tile/TileTeleposer.java index 6c1c09b5..aeff21a0 100644 --- a/src/main/java/WayofTime/bloodmagic/tile/TileTeleposer.java +++ b/src/main/java/WayofTime/bloodmagic/tile/TileTeleposer.java @@ -22,6 +22,7 @@ import net.minecraft.world.World; import net.minecraftforge.common.MinecraftForge; import java.util.List; +import java.util.UUID; public class TileTeleposer extends TileInventory implements ITickable { //TODO FUTURE: Make AreaDescriptor for Teleposer perhaps? @@ -98,34 +99,33 @@ public class TileTeleposer extends TileInventory implements ITickable { originalWorldEntities = getWorld().getEntitiesWithinAABB(Entity.class, originalArea); AxisAlignedBB focusArea = new AxisAlignedBB(focusPos.getX(), focusPos.getY() + 1, focusPos.getZ(), focusPos.getX() + 1, Math.min(focusWorld.getHeight(), focusPos.getY() + 2 * focusLevel), focusPos.getZ() + 1).expand(focusLevel - 1, 0, focusLevel - 1); focusWorldEntities = focusWorld.getEntitiesWithinAABB(Entity.class, focusArea); - + UUID bindingOwnerID = binding.getOwnerId(); if (focusWorld.equals(getWorld())) { if (!originalWorldEntities.isEmpty()) { for (Entity entity : originalWorldEntities) { - TeleportQueue.getInstance().addITeleport(new Teleports.TeleportSameDim(new BlockPos(entity.posX - pos.getX() + focusPos.getX(), entity.posY - pos.getY() + focusPos.getY(), entity.posZ - pos.getZ() + focusPos.getZ()), entity, binding.getOwnerId(), true)); + TeleportQueue.getInstance().addITeleport(new Teleports.TeleportSameDim(new BlockPos(entity.posX - pos.getX() + focusPos.getX(), entity.posY - pos.getY() + focusPos.getY(), entity.posZ - pos.getZ() + focusPos.getZ()), entity, bindingOwnerID, true)); } } if (!focusWorldEntities.isEmpty()) { for (Entity entity : focusWorldEntities) { - TeleportQueue.getInstance().addITeleport(new Teleports.TeleportSameDim(new BlockPos(entity.posX - pos.getX() + focusPos.getX(), entity.posY - pos.getY() + focusPos.getY(), entity.posZ - pos.getZ() + focusPos.getZ()), entity, binding.getOwnerId(), true)); + TeleportQueue.getInstance().addITeleport(new Teleports.TeleportSameDim(new BlockPos(entity.posX - pos.getX() + focusPos.getX(), entity.posY - pos.getY() + focusPos.getY(), entity.posZ - pos.getZ() + focusPos.getZ()), entity, bindingOwnerID, true)); + } + } + + } else { + if (!originalWorldEntities.isEmpty()) { + for (Entity entity : originalWorldEntities) { + TeleportQueue.getInstance().addITeleport(new Teleports.TeleportToDim(new BlockPos(entity.posX - pos.getX() + focusPos.getX(), entity.posY - pos.getY() + focusPos.getY(), entity.posZ - pos.getZ() + focusPos.getZ()), entity, bindingOwnerID, getWorld(), focusWorld.provider.getDimension(), true)); + } + } + + if (!focusWorldEntities.isEmpty()) { + for (Entity entity : focusWorldEntities) { + TeleportQueue.getInstance().addITeleport(new Teleports.TeleportToDim(new BlockPos(entity.posX - pos.getX() + focusPos.getX(), entity.posY - pos.getY() + focusPos.getY(), entity.posZ - pos.getZ() + focusPos.getZ()), entity, bindingOwnerID, focusWorld, getWorld().provider.getDimension(), true)); } } } - // FIXME - Fix cross-dimension teleports causing major desync -// } else { -// if (!originalWorldEntities.isEmpty()) { -// for (Entity entity : originalWorldEntities) { -// TeleportQueue.getInstance().addITeleport(new Teleports.TeleportToDim(new BlockPos(entity.posX - pos.getX() + focusPos.getX(), entity.posY - pos.getY() + focusPos.getY(), entity.posZ - pos.getZ() + focusPos.getZ()), entity, focusStack.getTagCompound().getString(Constants.NBT.OWNER_UUID), getWorld(), focusWorld.provider.getDimension(), true)); -// } -// } -// -// if (!focusWorldEntities.isEmpty()) { -// for (Entity entity : focusWorldEntities) { -// TeleportQueue.getInstance().addITeleport(new Teleports.TeleportToDim(new BlockPos(entity.posX - pos.getX() + focusPos.getX(), entity.posY - pos.getY() + focusPos.getY(), entity.posZ - pos.getZ() + focusPos.getZ()), entity, focusStack.getTagCompound().getString(Constants.NBT.OWNER_UUID), focusWorld, getWorld().provider.getDimension(), true)); -// } -// } -// } } } }