package joshie.harvest.mining; import joshie.harvest.core.helpers.ChatHelper; import joshie.harvest.core.helpers.TextHelper; import joshie.harvest.mining.tile.TileElevator; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent.WorldTickEvent; import javax.annotation.Nullable; import java.util.HashMap; public class TeleportPlayer { private static HashMap<EntityPlayer, TeleportTicker> SERVER_TICKER = new HashMap<>(); private static TeleportTicker CLIENT_TICKER; public static boolean isTeleportTargetSetTo(EntityPlayer player, BlockPos target) { if (!player.worldObj.isRemote) { TeleportTicker teleport = SERVER_TICKER.get(player); return teleport != null && teleport.location.equals(target); } else return CLIENT_TICKER != null && CLIENT_TICKER.location.equals(target); } public static void setTeleportTargetTo(EntityPlayer player, BlockPos twin, TileEntity target, BlockPos origin) { TeleportTicker ticker = new TeleportTicker(player, twin, target, origin); if (!player.worldObj.isRemote) { SERVER_TICKER.put(player, ticker); } else CLIENT_TICKER = ticker; MinecraftForge.EVENT_BUS.register(ticker); } private static void clearTeleportTarget(EntityPlayer player) { if (!player.worldObj.isRemote) SERVER_TICKER.remove(player); else CLIENT_TICKER = null; } private static class TeleportTicker { private final EntityPlayer player; private final BlockPos location; private final TileElevator target; private final BlockPos origin; private long worldTime; private int counter; TeleportTicker(EntityPlayer player, BlockPos twin, @Nullable TileEntity target, BlockPos origin) { this.player = player; this.location = twin; this.target = target instanceof TileElevator ? (TileElevator) target : null; this.origin = origin; int floors = MiningHelper.getDifference(twin, origin); this.counter = Math.min(600, Math.max(60, 5 * floors)); } private void finishOrCancelTeleport() { MinecraftForge.EVENT_BUS.unregister(this); clearTeleportTarget(player); if (counter <= 30 && player.worldObj.isRemote) { ChatHelper.displayChat(TextHelper.translate("elevator.done")); } } @SubscribeEvent public void onWorldTick(WorldTickEvent event) { if (isCollidingWithOrigin()) { if (worldTime != 0 && player.worldObj.getTotalWorldTime() == worldTime) return; else worldTime = player.worldObj.getTotalWorldTime(); counter--; if (counter > 0 && player.worldObj.isRemote && counter %20 == 0) { ChatHelper.displayChat(TextHelper.formatHF("elevator.wait", (int) Math.floor(counter / 20))); } if (counter <= 0) { finishOrCancelTeleport(); if (!player.worldObj.isRemote) { if (target != null) { EnumFacing facing = target.getFacing(); float yaw = facing == EnumFacing.WEST ? 90F : facing == EnumFacing.EAST ? -90F : facing == EnumFacing.NORTH ? 180F : 0F; MiningHelper.teleportToCoordinates(player, location.offset(facing), yaw); } } } } else finishOrCancelTeleport(); } private boolean isCollidingWithOrigin() { AxisAlignedBB axisalignedbb = player.getEntityBoundingBox(); BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain(axisalignedbb.minX + 0.001D, axisalignedbb.minY + 0.001D, axisalignedbb.minZ + 0.001D); BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos1 = BlockPos.PooledMutableBlockPos.retain(axisalignedbb.maxX - 0.001D, axisalignedbb.maxY - 0.001D, axisalignedbb.maxZ - 0.001D); BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos2 = BlockPos.PooledMutableBlockPos.retain(); if (player.worldObj.isAreaLoaded(blockpos$pooledmutableblockpos, blockpos$pooledmutableblockpos1)) { for (int i = blockpos$pooledmutableblockpos.getX(); i <= blockpos$pooledmutableblockpos1.getX(); ++i) { for (int j = blockpos$pooledmutableblockpos.getY(); j <= blockpos$pooledmutableblockpos1.getY(); ++j) { for (int k = blockpos$pooledmutableblockpos.getZ(); k <= blockpos$pooledmutableblockpos1.getZ(); ++k) { blockpos$pooledmutableblockpos2.setPos(i, j, k); if (blockpos$pooledmutableblockpos2.equals(origin) || blockpos$pooledmutableblockpos2.equals(origin.up())) { return true; } } } } } blockpos$pooledmutableblockpos.release(); blockpos$pooledmutableblockpos1.release(); blockpos$pooledmutableblockpos2.release(); return false; } } }