예제 #1
0
  public SpoutEntity(
      SpoutEngine engine,
      Transform transform,
      Controller controller,
      int viewDistance,
      UUID uid,
      boolean load) {
    id.set(NOTSPAWNEDID);
    this.transform.set(transform);

    if (uid != null) {
      this.uid = uid;
    } else {
      this.uid = UUID.randomUUID();
    }

    chunkLive = new AtomicReference<Chunk>();
    entityManagerLive = new AtomicReference<EntityManager>();
    controllerLive = new AtomicReference<Controller>();

    if (transform != null && load) {
      chunkLive.set(transform.getPosition().getWorld().getChunkFromBlock(transform.getPosition()));
      entityManagerLive.set(((SpoutRegion) chunkLive.get().getRegion()).getEntityManager());
    }

    viewDistanceLive.set(viewDistance);

    controllerLive.set(controller);
    if (controller != null) {
      controller.attachToEntity(this);
      if (controller instanceof PlayerController) {
        setObserver(true);
      }
    }
  }
예제 #2
0
 @Override
 public void updateView() {
   Transform transform =
       ((PredictableTransformComponent) getOwner().getTransform()).getRenderTransform();
   if (transform != null) {
     Matrix pos = MathHelper.translate(transform.getPosition().multiply(-1));
     Matrix rot = MathHelper.rotate(transform.getRotation());
     view = pos.multiply(rot);
     frustum.update(projection, view, transform.getPosition());
   }
 }
예제 #3
0
 private void updateObserver() {
   // Player view distance is handled in the network synchronizer
   if (controllerLive.get() instanceof PlayerController) {
     return;
   }
   int viewDistance = (getViewDistance() + 15) / Chunk.CHUNK_SIZE; // round up
   World w = transform.getPosition().getWorld();
   int cx = chunkLive.get().getX();
   int cy = chunkLive.get().getY();
   int cz = chunkLive.get().getZ();
   HashSet<SpoutChunk> observing =
       new HashSet<SpoutChunk>(viewDistance * viewDistance * viewDistance);
   for (int dx = -viewDistance; dx < viewDistance; dx++) {
     for (int dy = -viewDistance; dy < viewDistance; dy++) {
       for (int dz = -viewDistance; dz < viewDistance; dz++) {
         Chunk chunk = w.getChunk(cx + dx, cy + dy, cz + dz, true);
         chunk.refreshObserver(this);
         observing.add((SpoutChunk) chunk);
       }
     }
   }
   observingChunks.removeAll(observing);
   for (SpoutChunk chunk : observingChunks) {
     if (chunk.isLoaded()) {
       chunk.removeObserver(this);
     }
   }
   observingChunks.clear();
   observingChunks.addAll(observing);
 }
예제 #4
0
  @Override
  public void onTick(float dt) {
    Controller cont = controllerLive.get();
    // Pulse all player messages here, so they can interact with the entities position safely
    if (cont instanceof PlayerController) {
      Player player = ((PlayerController) cont).getPlayer();
      if (player != null && player.getSession() != null) {
        ((SpoutSession) player.getSession()).pulse();
      }
    }

    // Tick the controller
    if (cont != null) {
      // Sanity check
      if (cont.getParent() != this) {
        if (Spout.debugMode()) {
          throw new IllegalStateException("Controller parent does not match entity");
        } else {
          cont.attachToEntity(this);
        }
      }
      // If this is the first tick, we need to attach the controller
      // Controller is attached here instead of inside of the constructor
      // because the constructor can not access getChunk if the entity is being deserialized
      if (!attached) {
        cont.onAttached();
        attached = true;
      }
      cont.onTick(dt);
    }

    // Copy values last (position may change during controller or session pulses)
    if (!isDead()
        && this.transform.getPosition() != null
        && this.transform.getPosition().getWorld() != null) {
      // Note: if the chunk is null, this effectively kills the entity (since dead: {chunkLive.get()
      // == null})
      chunkLive.set(
          transform.getPosition().getWorld().getChunkFromBlock(transform.getPosition(), false));

      entityManagerLive.set(((SpoutRegion) getRegion()).getEntityManager());
      lastTransform = transform.copy();
    }
  }
예제 #5
0
 @Override
 public BlockIterator getAlignedBlocks() {
   Player player = (Player) getOwner();
   Transform ptr = player.get(PlayerHead.class).getHeadTransform();
   Transform tr = new Transform();
   tr.setRotation(
       QuaternionMath.rotationTo(Vector3.FORWARD, ptr.getRotation().getDirection().multiply(-1)));
   tr.setPosition(ptr.getPosition());
   return new BlockIterator(player.getWorld(), tr, getRange());
 }
예제 #6
0
 @DelayedWrite
 public boolean connect(SpoutSession<?> session, Transform newTransform) {
   if (!onlineLive.compareAndSet(false, true)) {
     // player was already online
     return false;
   }
   // Disallow null transforms or transforms with null worlds
   if (newTransform == null || newTransform.getPosition().getWorld() == null) {
     return false;
   }
   getTransform().setTransform(newTransform);
   setupInitialChunk(newTransform);
   sessionLive.set(session);
   copySnapshot();
   return true;
 }
예제 #7
0
 @Override
 public Transform convert(Transform t) {
   return new Transform(convert(t.getPosition()), t.getRotation(), t.getScale());
 }
예제 #8
0
  @Override
  public List<Message> getUpdateMessages(
      Entity entity, Transform liveTransform, RepositionManager rm, boolean force) {
    // Movement
    final Transform prevTransform = rm.convert(entity.getScene().getTransform());
    final Transform newTransform = rm.convert(liveTransform);

    final boolean looked = entity.getScene().isRotationDirty();

    final int lastX = protocolifyPosition(prevTransform.getPosition().getX());
    final int lastY = protocolifyPosition(prevTransform.getPosition().getY());
    final int lastZ = protocolifyPosition(prevTransform.getPosition().getZ());
    final int lastYaw = protocolifyYaw(prevTransform.getRotation().getYaw());
    final int lastPitch = protocolifyPitch(prevTransform.getRotation().getPitch());

    final int newX = protocolifyPosition(newTransform.getPosition().getX());
    final int newY = protocolifyPosition(newTransform.getPosition().getY());
    final int newZ = protocolifyPosition(newTransform.getPosition().getZ());
    final int newYaw = protocolifyYaw(newTransform.getRotation().getYaw());
    final int newPitch = protocolifyPitch(newTransform.getRotation().getPitch());

    final int deltaX = newX - lastX;
    final int deltaY = newY - lastY;
    final int deltaZ = newZ - lastZ;
    final int deltaYaw = newYaw - lastYaw;
    final int deltaPitch = newPitch - lastPitch;

    final List<Message> messages = new ArrayList<Message>();

    /*
     * Two scenarios:
     * - The entity moves more than 4 blocks and maybe changes rotation.
     * - The entity moves less than 4 blocks and maybe changes rotation.
     */
    if (force
        || deltaX > 128
        || deltaX < -128
        || deltaY > 128
        || deltaY < -128
        || deltaZ > 128
        || deltaZ < -128) {
      messages.add(new EntityTeleportMessage(entity.getId(), newX, newY, newZ, newYaw, newPitch));
      if (force || looked) {
        messages.add(new EntityYawMessage(entity.getId(), newYaw, newPitch));
      }
    } else if (deltaX != 0 || deltaY != 0 || deltaZ != 0 || deltaYaw != 0 || deltaPitch != 0) {
      if (looked) {
        messages.add(
            new EntityRelativePositionYawMessage(
                entity.getId(), deltaX, deltaY, deltaZ, newYaw, newPitch));
      } else if (!prevTransform.getPosition().equals(newTransform.getPosition())) {
        messages.add(new EntityRelativePositionMessage(entity.getId(), deltaX, deltaY, deltaZ));
      }
    }

    // Head movement
    HeadComponent head = entity.get(HeadComponent.class);
    if (head != null && head.isDirty()) {
      final int headYawProt = ChannelBufferUtils.protocolifyYaw(head.getRotation().getYaw());
      messages.add(new EntityHeadYawMessage(entity.getId(), headYawProt));
    }

    // Physics
    // TODO: Actually not used?
    /*if (physics != null && physics.isLinearVelocityDirty()) {
    	messages.add(new EntityVelocityMessage(entity.getId(), new Vector3(0, 0, 0)));
    }*/

    // Extra metadata
    List<Parameter<?>> params = getUpdateParameters(entity);
    if (lastMeta == null || !lastMeta.equals(params)) {
      messages.add(new EntityMetadataMessage(entity.getId(), params));
      lastMeta = params;
    }

    return messages;
  }
예제 #9
0
 @Override
 public World getWorld() {
   return transform.getPosition().getWorld();
 }
예제 #10
0
 @Override
 public Point getPosition() {
   return transform.getPosition();
 }