package org.pokenet.server.backend.entity;
import java.util.LinkedList;
import java.util.Queue;
import org.pokenet.server.backend.map.ServerMap;
import org.pokenet.server.network.message.SpriteChangeMessage;
/**
* Base class for a character. Note: Originally this implemented Battleable but not all chars are battleable
* @author shadowkanji
*
*/
public class Char implements Positionable {
private Direction m_facing = Direction.Down;
protected int m_sprite, m_mapX, m_mapY, m_x, m_y, m_id;
private boolean m_isVisible, m_isSurfing;
protected String m_name;
protected ServerMap m_map;
private boolean m_boostPriority = false;
/*
* Stores a queue of movements for processing
*/
protected Queue<Direction> m_movementQueue = new LinkedList<Direction>();
/**
* Returns the priority of this player to be move checked
* @return
*/
public int getPriority() {
if(m_boostPriority) {
m_boostPriority = false;
return m_movementQueue.size() + 100;
}
return m_movementQueue.size();
}
/**
* Boost the char's movement priority
*/
public void boostPriority() {
m_boostPriority = true;
}
/**
* Queues a movement to be checked
* @param d
*/
public void queueMovement(Direction d) {
m_movementQueue.offer(d);
}
/**
* Returns next movement to be checked
* @return
*/
public Direction getNextMovement() {
if(m_movementQueue.size() == 0)
return null;
return m_movementQueue.poll();
}
/**
* Returns the direction this char is facing
*/
public Direction getFacing() {
return m_facing;
}
/**
* Returms the map this char is on
*/
public ServerMap getMap() {
return m_map;
}
/**
* Returns the mapX of this char
*/
public int getMapX() {
return m_mapX;
}
/**
* Returns the mayY of this char
*/
public int getMapY() {
return m_mapY;
}
/**
* Returns the raw sprite (ignoring surf)
* @return
*/
public int getRawSprite() {
return m_sprite;
}
/**
* Returns the sprite of this char. Will return the surf sprite if the char is surfing
*/
public int getSprite() {
return m_isSurfing ? -1 : m_sprite;
}
/**
* Returns the x co-ordinate of this char
*/
public int getX() {
return m_x;
}
/**
* Returns the y co-ordinate of this char
*/
public int getY() {
return m_y;
}
/**
* Returns if this char is visible
*/
public boolean isVisible() {
return m_isVisible;
}
/**
* Sets the map this player is and handles all networking to client that is involved with it
*/
public void setMap(ServerMap map, Direction dir) {
//Remove the char from their old map
if(m_map != null)
m_map.removeChar(this);
//Set their current map to the new map
m_map = map;
m_mapX = map.getX();
m_mapY = map.getY();
//Add the char to the map
m_map.addChar(this);
}
/**
* Set the sprite of this char
*/
public void setSprite(int sprite) {
m_sprite = sprite;
//Inform everyone of sprite change
if(m_map != null)
m_map.sendToAll(new SpriteChangeMessage(m_id, this.getSprite()));
}
/**
* Set if this char is visible
*/
public void setVisible(boolean visible) {
m_isVisible = visible;
}
/**
* Returns the name of the char
*/
public String getName() {
return m_name.equalsIgnoreCase("SPRITER") ? "" : m_name;
}
/**
* Sets the name of this char
* NOTE: For PlayerChar's this is their username
* @param name
*/
public void setName(String name) {
m_name = name;
}
/**
* Processes and checks all movements queued
*/
public void move() {
/*
* Moves player until queue becomes empty,
* collision encountered or pokemon encountered
*/
while(move(getNextMovement())) {}
}
/**
* Returns true if the char was successfully moved in direction d
* @param d - Direction to be moved in
*/
public boolean move(Direction d) {
if(d != null && m_map != null) {
//Change direction if needs be
if(m_facing != d) {
setFacing(d);
return true;
}
//Move the player
if(m_map.moveChar(this, d)) {
/*
* Update co-ordinates and inform other players of movement
*/
switch(d) {
case Up:
m_y -= 32;
m_facing = Direction.Up;
m_map.sendMovementToAll(d, this);
break;
case Down:
m_y += 32;
m_facing = Direction.Down;
m_map.sendMovementToAll(d, this);
break;
case Left:
m_x -= 32;
m_facing = Direction.Left;
m_map.sendMovementToAll(d, this);
break;
case Right:
m_x += 32;
m_facing = Direction.Right;
m_map.sendMovementToAll(d, this);
break;
}
return true;
} else {
//Invalid movement
if(this instanceof PlayerChar) {
//If its a player, resync them
PlayerChar p = (PlayerChar) this;
p.getTcpSession().write("U" + getX() + "," + getY());
return false;
}
}
}
return false;
}
/**
* Returns this char's id
*/
public int getId() {
return m_id;
}
/**
* Sets this char's id.
* NOTE: PlayerChars ids are permanent, given upon registration
* NOTE: NonPlayerChars ids are dynamic, based on how many other npcs are on the same map
*/
public void setId(int id) {
m_id = id;
}
/**
* Returns if two chars are the same based on id
* @param c
* @return
*/
public boolean equals(Char c) {
return m_id == c.getId();
}
/**
* Sets the x co-ordinate of this character on the map
*/
public void setX(int x) {
m_x = x;
}
/**
* Sets the y co-ordinate of this character on the map
*/
public void setY(int y) {
m_y = y;
}
/**
* Sets the map x co-ordinate
* @param x
*/
public void setMapX(int x) {
m_mapX = x;
}
/**
* Sets the map y co-ordinate
* @param y
*/
public void setMapY(int y) {
m_mapY = y;
}
/**
* Sets if this char is surfing or not and sends the sprite change information to everyone
* @param b
*/
public void setSurfing(boolean b) {
m_isSurfing = b;
if(m_map != null)
m_map.sendToAll(new SpriteChangeMessage(m_id, this.getSprite()));
}
/**
* Returns true if this char is surfing
* @return
*/
public boolean isSurfing() {
return m_isSurfing;
}
/**
* Disposes of this char
*/
public void dispose() {
m_map = null;
}
/**
* Changes the direction of the npc
* @param d
*/
public void setFacing(Direction d) {
m_facing = d;
if(m_map != null) {
m_map.sendMovementToAll(d, this);
}
}
}