Package crazypants.enderio.rail

Source Code of crazypants.enderio.rail.EnderRailController$PlayerTpInfo

package crazypants.enderio.rail;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
import java.util.UUID;

import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.item.EntityMinecart;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagString;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.util.ForgeDirection;
import crazypants.enderio.config.Config;
import crazypants.enderio.machine.transceiver.TileTransceiver;
import crazypants.util.BlockCoord;
import crazypants.util.EntityUtil;
import crazypants.util.ForgeDirectionOffsets;
import crazypants.vecmath.Vector3d;

public class EnderRailController {

  //keep track of which carts we have received have left the track as they can't be teleported again until they have
  private final Set<UUID> newlySpawnedCarts = new HashSet<UUID>();

  private final LinkedList<List<Entity>> cartsToSpawn = new LinkedList<List<Entity>>();
  private final List<PlayerTpInfo> playersToRemount = new ArrayList<EnderRailController.PlayerTpInfo>();

  private int ticksFailedToSpawn = 0;

  private NBTTagList cartList;

  private final TileTransceiver transciever;

  public EnderRailController(TileTransceiver tileTransceiver) {
    transciever = tileTransceiver;
  }

  public void doTick() {

    if(cartList != null) {
      loadCartsToSpawn();
      cartList = null;
    }

    spawnRecievedCart();

    List<EntityMinecart> carts = getMinecartsOnTrack();
    List<UUID> toRemove = new ArrayList<UUID>();

    //any cart in the newly spawned list no longer on the track needs to be removed   
    for (UUID recievedCartUID : newlySpawnedCarts) {
      EntityMinecart minecart = getMinecartWthUUID(recievedCartUID, carts);
      if(minecart == null) {
        toRemove.add(recievedCartUID);
      }
    }
    for (UUID recievedCart : toRemove) {
      newlySpawnedCarts.remove(recievedCart);
    }
  }

  private EntityMinecart getMinecartWthUUID(UUID recievedCartUID, Collection<EntityMinecart> carts) {
    for (EntityMinecart cart : carts) {
      if(recievedCartUID.equals(cart.getPersistentID())) {
        return cart;
      }
    }
    return null;
  }

  private void spawnRecievedCart() {

    if(Config.enderRailTeleportPlayers) {
      ListIterator<PlayerTpInfo> li = playersToRemount.listIterator();
      while (li.hasNext()) {
        PlayerTpInfo tpi = li.next();
        if(tpi.attemptMount() || tpi.attemptsRemaining <= 0) {
          li.remove();
        }
      }
    }

    if(cartsToSpawn.isEmpty()) {
      ticksFailedToSpawn = 0;
      return;
    }
    boolean failedSpawn = false;
    if(!isClear()) {
      ticksFailedToSpawn++;
      if(ticksFailedToSpawn < Config.enderRailTicksBeforeForceSpawningLinkedCarts) {
        return;
      }
      failedSpawn = true;
    }
    List<Entity> spawnThisTick = cartsToSpawn.removeFirst();
    for (Entity ent : spawnThisTick) {
      if(failedSpawn) {
        doRandomSpawn(ent);
      } else {
        EntityMinecart cart = null;
        if(ent instanceof EntityMinecart) {
          cart = (EntityMinecart) ent;
          setCartDirection(cart);
        }       
        TeleportUtil.spawn(transciever.getWorldObj(), ent);
        if(cart != null) {         
          newlySpawnedCarts.add(cart.getPersistentID());
          CartLinkUtil.recreateLinks(cart);
        }
      }
    }

    ticksFailedToSpawn = 0;

  }

  private void setCartDirection(EntityMinecart cart) {
    int meta = transciever.getWorldObj().getBlockMetadata(transciever.xCoord, transciever.yCoord + 1, transciever.zCoord);
    ForgeDirection dir = BlockEnderRail.getDirection(meta);
    double velocity = Math.max(Math.abs(cart.motionX), Math.abs(cart.motionZ));
    cart.motionX = dir.offsetX * velocity;
    cart.motionZ = dir.offsetZ * velocity;
   
  }

  public void onTrainRecieved(List<List<Entity>> toTeleport) {
    cartsToSpawn.addAll(toTeleport);
  }

  public boolean isRecievedCart(EntityMinecart mc) {
    return newlySpawnedCarts.contains(mc.getPersistentID());
  }

  public boolean isClear() {
    World worldObj = transciever.getWorldObj();

    BlockCoord railCoord = new BlockCoord(transciever).getLocation(ForgeDirection.UP);
    int meta = worldObj.getBlockMetadata(railCoord.x, railCoord.y, railCoord.z);

    double buf = 1;
    ForgeDirection dir = BlockEnderRail.getDirection(meta);
    Vector3d offset = ForgeDirectionOffsets.forDirCopy(dir);
    offset.scale(buf);
    offset.x = Math.abs(offset.x);
    offset.z = Math.abs(offset.z);
    List res = worldObj.getEntitiesWithinAABB(Entity.class, AxisAlignedBB.getBoundingBox(railCoord.x - offset.x, railCoord.y,
        railCoord.z - offset.z, railCoord.x + 1 + offset.x, railCoord.y + 1, railCoord.z + 1 + offset.z));
    return res == null || res.isEmpty();
  }

  public List<EntityMinecart> getMinecartsOnTrack() {
    return getMinecartsAt(transciever.getWorldObj(), transciever.xCoord, transciever.yCoord + 1, transciever.zCoord);
  }

  public static List<EntityMinecart> getMinecartsAt(World world, int x, int y, int z) {
    List entities = world.getEntitiesWithinAABB(EntityMinecart.class, AxisAlignedBB.getBoundingBox(x, y, z, x + 1, y + 1, z + 1));
    List<EntityMinecart> carts = new ArrayList<EntityMinecart>();
    for (Object o : entities) {
      EntityMinecart cart = (EntityMinecart) o;
      if(!cart.isDead) {
        carts.add((EntityMinecart) o);
      }
    }
    return carts;
  }

  private void loadCartsToSpawn() {
    World worldObj = transciever.getWorldObj();
    while (cartList.tagCount() > 0) {
      NBTTagList entityList = (NBTTagList) cartList.removeTag(0);
      List<Entity> ents = new ArrayList<Entity>(entityList.tagCount());
      for (int i = 0; i < entityList.tagCount(); i++) {
        NBTTagCompound entityRoot = entityList.getCompoundTagAt(i);
        Entity entity = EntityList.createEntityFromNBT(entityRoot, worldObj);
        if(entity != null) {
          ents.add(entity);
        }
      }
      cartsToSpawn.add(ents);
    }
  }

  public void readFromNBT(NBTTagCompound root) {
    cartsToSpawn.clear();
    if(!root.hasKey("cartList")) {
      return;
    }
    cartList = (NBTTagList) root.getTag("cartList");

    newlySpawnedCarts.clear();
    if(root.hasKey("newlySpawnedCarts")) {
      NBTTagList spawnedCartList = (NBTTagList) root.getTag("newlySpawnedCarts");
      for (int i = 0; i < spawnedCartList.tagCount(); i++) {
        String uuisStr = spawnedCartList.getStringTagAt(i);
        newlySpawnedCarts.add(UUID.fromString(uuisStr));
      }
    }
  }

  public void writeToNBT(NBTTagCompound root) {
    if(cartsToSpawn.isEmpty()) {
      return;
    }
    NBTTagList cartList = new NBTTagList();

    for (List<Entity> entsInCart : cartsToSpawn) {
      if(entsInCart != null && !entsInCart.isEmpty()) {
        NBTTagList entityList = new NBTTagList();
        cartList.appendTag(entityList);
        for (Entity entity : entsInCart) {
          NBTTagCompound entRoot = new NBTTagCompound();
          entRoot.setString("id", EntityList.getEntityString(entity));
          entity.writeToNBT(entRoot);
          entityList.appendTag(entRoot);
        }
      }
    }
    root.setTag("cartList", cartList);

    if(!newlySpawnedCarts.isEmpty()) {
      NBTTagList spawnedCartList = new NBTTagList();
      for (UUID uuid : newlySpawnedCarts) {
        spawnedCartList.appendTag(new NBTTagString(uuid.toString()));
      }
      root.setTag("newlySpawnedCarts", spawnedCartList);
    }
  }

  public void dropNonSpawnedCarts() {
    if(cartsToSpawn.isEmpty()) {
      return;
    }
    for (List<Entity> entList : cartsToSpawn) {
      for (Entity entity : entList) {
        doRandomSpawn(entity);
      }
    }
    cartsToSpawn.clear();

  }

  private void doRandomSpawn(Entity entity) {
    if(entity == null) {
      return;
    }
    double oX = entity.posX;
    double oZ = entity.posZ;
    World world = transciever.getWorldObj();
    MinecraftServer minecraftserver = MinecraftServer.getServer();
    WorldServer worldserver = minecraftserver.worldServerForDimension(world.provider.dimensionId);
    for (int i = 0; i < 4; i++) {
      int x = transciever.xCoord + randOffset(2);
      int y = transciever.yCoord + 1;
      int z = transciever.zCoord + randOffset(2);
      Block b = world.getBlock(x, y, z);
      entity.setPosition(x + 0.5, entity.posY, z + 0.5);
      if(world.canPlaceEntityOnSide(b, x, y, z, false, ForgeDirection.UP.ordinal(), entity, null)) {
        resetForRandomRandomSpawn(entity);
        if(worldserver.spawnEntityInWorld(entity)) {
          //entity.onUpdate();
          worldserver.updateEntity(entity);
          return;
        }
      }
    }
    entity.setPosition(oX, entity.posY, oZ);
    resetForRandomRandomSpawn(entity);
    worldserver.spawnEntityInWorld(entity);
  }

  private void resetForRandomRandomSpawn(Entity entity) {
    CartLinkUtil.breakLinks(transciever.getWorldObj(), entity);
    entity.riddenByEntity = null;
    entity.ridingEntity = null;
    entity.motionX = 0;
    entity.motionY = 0;
    entity.motionZ = 0;
    //    if(entity instanceof EntityMinecart) {
    //      entity.posY -= 0.3;     
    //    }
    entity.prevPosX = entity.posX;
    entity.prevPosY = entity.posY;
    entity.prevPosZ = entity.posZ;
    entity.rotationYaw = (float) (transciever.getWorldObj().rand.nextDouble() * 360);
  }

  private int randOffset(int spread) {
    return (int) Math.round((transciever.getWorldObj().rand.nextDouble() - 0.5) * spread * 2);
  }

  public void onPlayerTeleported(EntityPlayerMP playerToTP, EntityMinecart toMount) {
    if(playerToTP != null) {
      playersToRemount.add(new PlayerTpInfo(playerToTP.getCommandSenderName(), toMount.getPersistentID(), 20));
    }
  }

  private class PlayerTpInfo {
    String playerName;
    UUID cartId;
    int attemptsRemaining;

    PlayerTpInfo(String playerName, UUID cartId, int attemptsRemaining) {
      this.playerName = playerName;
      this.cartId = cartId;
      this.attemptsRemaining = attemptsRemaining;
    }

    boolean attemptMount() {
      attemptsRemaining--;
      List<EntityMinecart> carts = getMinecartsOnTrack();
      for (EntityMinecart cart : carts) {
        if(cart != null && cart.getPersistentID().equals(cartId)) {
          EntityPlayer player = transciever.getWorldObj().getPlayerEntityByName(playerName);
          if(player != null) {
            Vector3d playerPos = EntityUtil.getEntityPosition(player);
            Vector3d cartPos = EntityUtil.getEntityPosition(cart);
            if(playerPos.distanceSquared(cartPos) <= 9) {
              player.posX = cart.posX;
              player.posY = cart.posY;
              player.posZ = cart.posZ;
              player.mountEntity(cart);
              return true;
            }
          }
        }
      }
      return false;
    }

  }

}
TOP

Related Classes of crazypants.enderio.rail.EnderRailController$PlayerTpInfo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.