Package net.lightstone.model

Source Code of net.lightstone.model.Player

package net.lightstone.model;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import net.lightstone.msg.ChatMessage;
import net.lightstone.msg.DestroyEntityMessage;
import net.lightstone.msg.LoadChunkMessage;
import net.lightstone.msg.Message;
import net.lightstone.msg.PingMessage;
import net.lightstone.msg.PositionRotationMessage;
import net.lightstone.msg.SpawnPlayerMessage;
import net.lightstone.msg.EntityMetadataMessage;
import net.lightstone.net.Session;
import net.lightstone.util.Parameter;

/**
* Represents an in-game player.
* @author Graham Edgecombe
*/
public final class Player extends Mob {

  /**
   * The normal height of a player's eyes above their feet.
   */
  public static final double NORMAL_EYE_HEIGHT = 1.62D;

  /**
   * The height of a player's eyes above their feet when they are crouching.
   */
  public static final double CROUCH_EYE_HEIGHT = 1.42D;

  /**
   * The name of this player.
   */
  private final String name;

  /**
   * This player's session.
   */
  private final Session session;

  /**
   * The entities that the client knows about.
   */
  private Set<Entity> knownEntities = new HashSet<Entity>();

  /**
   * The chunks that the client knows about.
   */
  private Set<Chunk.Key> knownChunks = new HashSet<Chunk.Key>();

  /**
   * A flag that indicates if this player is crouching.
   */
  private boolean crouching = false;

  /**
   * Creates a new player and adds it to the world.
   * @param session The player's session.
   * @param name The player's name.
   */
  public Player(Session session, String name) {
    super(session.getServer().getWorld());
    this.name = name;
    this.session = session;

    // stream the initial set of blocks and teleport us
    this.streamBlocks();
    this.position = world.getSpawnPosition();
    this.sendMessage("§eWelcome to Lightstone, " + name + "!");
    this.session.send(new PositionRotationMessage(position.getX(), position.getY(), position.getZ(), position.getY() + NORMAL_EYE_HEIGHT, (float) rotation.getYaw(), (float) rotation.getPitch(), true));
  }

  /**
   * Gets the name of this player.
   * @return The name of this player.
   */
  public String getName() {
    return name;
  }

  /**
   * A convenience method for sending a message to this player.
   * @param message The message.
   */
  public void sendMessage(String message) {
    session.send(new ChatMessage(message));
  }

  @Override
  public void pulse() {
    super.pulse();
    session.send(new PingMessage());

    streamBlocks();

    for (Iterator<Entity> it = knownEntities.iterator(); it.hasNext(); ) {
      Entity entity = it.next();
      boolean withinDistance = entity.isActive() && isWithinDistance(entity);

      if (withinDistance) {
        Message msg = entity.createUpdateMessage();
        if (msg != null)
          session.send(msg);
      } else {
        session.send(new DestroyEntityMessage(entity.getId()));
        it.remove();
      }
    }

    for (Entity entity : world.getEntities()) {
      if (entity == this)
        continue;
      boolean withinDistance = entity.isActive() && isWithinDistance(entity);

      if (withinDistance && !knownEntities.contains(entity)) {
        knownEntities.add(entity);
        session.send(entity.createSpawnMessage());
      }
    }
  }

  /**
   * Streams chunks to the player's client.
   */
  private void streamBlocks() {
    Set<Chunk.Key> previousChunks = new HashSet<Chunk.Key>(knownChunks);

    int centralX = ((int) position.getX()) / Chunk.WIDTH;
    int centralZ = ((int) position.getZ()) / Chunk.HEIGHT;

    for (int x = (centralX - Chunk.VISIBLE_RADIUS); x <= (centralX + Chunk.VISIBLE_RADIUS); x++) {
      for (int z = (centralZ - Chunk.VISIBLE_RADIUS); z <= (centralZ + Chunk.VISIBLE_RADIUS); z++) {
        Chunk.Key key = new Chunk.Key(x, z);
        if (!knownChunks.contains(key)) {
          knownChunks.add(key);
          session.send(new LoadChunkMessage(x, z, true));
          session.send(world.getChunks().getChunk(x, z).toMessage());
        }
        previousChunks.remove(key);
      }
    }

    for (Chunk.Key key : previousChunks) {
      session.send(new LoadChunkMessage(key.getX(), key.getZ(), false));
      knownChunks.remove(key);
    }

    previousChunks.clear();
  }

  /**
   * Gets the session.
   * @return The session.
   */
  public Session getSession() {
    return session;
  }

  @Override
  public Message createSpawnMessage() {
    int x = position.getPixelX();
    int y = position.getPixelY();
    int z = position.getPixelZ();
    int yaw = rotation.getIntYaw();
    int pitch = rotation.getIntPitch();
    return new SpawnPlayerMessage(id, name, x, y, z, yaw, pitch, 0);
  }

  /**
   * Sets the crouching flag.
   * @param crouching The crouching flag.
   */
  public void setCrouching(boolean crouching) {
    // TODO: update other clients, needs to be figured out
    this.crouching = crouching;
    setMetadata(new Parameter<Byte>(Parameter.TYPE_BYTE, 0, new Byte((byte) (crouching ? 0x02: 0))));
    // FIXME: other bits in the bitmask would be wiped out
    EntityMetadataMessage message = new EntityMetadataMessage(id, metadata.clone());
    for (Player player : world.getPlayers()) { // TODO: this only needs to be sent to local players I think
      if (player != this) {
        player.getSession().send(message);
      }
    }
  }

  /**
   * Gets the crouching flag.
   * @return The crouching flag.
   */
  public boolean isCrouching() {
    return crouching;
  }

}
TOP

Related Classes of net.lightstone.model.Player

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.