package org.pokenet.client.backend;
import java.util.Iterator;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.tiled.Layer;
import org.newdawn.slick.tiled.TiledMap;
import org.pokenet.client.GameClient;
import org.pokenet.client.backend.entity.HMObject;
import org.pokenet.client.backend.entity.Player;
import org.pokenet.client.backend.entity.Player.Direction;
/**
* Represents a map to be rendered on screen
*
* @author shadowkanji
* @author ZombieBear
*
*/
public class ClientMap extends TiledMap {
// map offset modifiers
private int m_xOffsetModifier;
private int m_yOffsetModifier;
private int m_xOffset;
private int m_yOffset;
private int m_mapX;
private int m_mapY;
public int m_x;
public int m_y;
private boolean m_isCurrent = false;
private ClientMapMatrix m_mapMatrix;
private int m_walkableLayer;
private String m_name;
private Image m_grassOverlay;
/**
* Default constructor
*
* @param f
* @param tileSetsLocation
* @throws SlickException
*/
public ClientMap(String tileSetsLocation)
throws SlickException {
super(tileSetsLocation);
String respath = System.getProperty("res.path");
if(respath==null)
respath="";
try {
m_grassOverlay = new Image(respath+"res/ui/grass_overlay.png", false);
} catch (Exception e) {
e.printStackTrace();
}
m_xOffsetModifier = Integer.parseInt(getMapProperty("xOffsetModifier",
"0").trim());
m_yOffsetModifier = Integer.parseInt(getMapProperty("yOffsetModifier",
"0").trim());
m_xOffset = m_xOffsetModifier;
m_yOffset = m_yOffsetModifier;
}
/**
* Returns true if this map is/should be rendering on screen
*
* @return
*/
public boolean isRendering() {
int drawWidth = getXOffset() + getWidth() * 32;
int drawHeight = getYOffset() + getHeight() * 32;
if (!(drawWidth < -32 && getXOffset() < -32 || drawWidth > 832
&& getXOffset() > 832)
&& !(drawHeight < -32 && getYOffset() < -32 || drawHeight > 632
&& getYOffset() > 632)) {
return true;
}
return false;
}
/**
* Returns the X offset of this map
*
* @return
*/
public int getXOffset() {
return m_xOffset;
}
/**
* Returns the Y offset of this map
*
* @return
*/
public int getYOffset() {
return m_yOffset;
}
/**
* Returns the index of the walkable layer
*
* @return
*/
public int getWalkableLayer() {
return m_walkableLayer;
}
/**
* Set to true if this is at 1,1 in the map matrix
*
* @param b
*/
public void setCurrent(boolean b) {
m_isCurrent = b;
}
/**
* Returns true if this is 1,1 in the map matrix
*
* @return
*/
public boolean isCurrent() {
return m_isCurrent;
}
/**
* Sets the map matrix
*
* @param m
*/
public void setMapMatrix(ClientMapMatrix m) {
m_mapMatrix = m;
}
/**
* Sets the map x (in map matrix)
*
* @param x
*/
public void setMapX(int x) {
m_mapX = x;
}
/**
* Sets the map y (in map matrix)
*
* @param y
*/
public void setMapY(int y) {
m_mapY = y;
}
/**
* Returns the x offset modifier
*
* @return
*/
public int getXOffsetModifier() {
return m_xOffsetModifier;
}
/**
* Returns the y offset modifier
*
* @return
*/
public int getYOffsetModifier() {
return m_yOffsetModifier;
}
/**
* Returns true if x or y if off the map
*
* @param x
* @param y
* @return
*/
private boolean isNewMap(int x, int y) {
return x < 0 || x >= this.getWidth() * 32 || y < 0
|| y + 8 >= this.getHeight() * 32;
}
/**
* Reinitializes a map after shifting in the map matrix
*/
public void reinitialize(){
m_xOffsetModifier = Integer.parseInt(getMapProperty("xOffsetModifier", "0").trim());
m_yOffsetModifier = Integer.parseInt(getMapProperty("yOffsetModifier", "0").trim());
m_xOffset = m_xOffsetModifier;
m_yOffset = m_yOffsetModifier;
}
/**
* Returns true if the player is colliding with an object
*
* @param p
* @param d
* @return
*/
public boolean isColliding(Player p, Direction d) {
int newX = 0, newY = 0;
switch (d) {
case Up:
newX = p.getServerX();
newY = p.getServerY() - 32;
break;
case Down:
newX = p.getServerX();
newY = p.getServerY() + 32;
break;
case Left:
newX = p.getServerX() - 32;
newY = p.getServerY();
break;
case Right:
newX = p.getServerX() + 32;
newY = p.getServerY();
break;
}
if (isNewMap(newX, newY))
return false;
for (HMObject m_hmObj : m_mapMatrix.getHMObjects()){
if (m_hmObj.getX() == newX && m_hmObj.getY() == newY){
return true;
}
}
int collisionLayer = 0;
int waterLayer = 0;
int ledgeLayer = 0;
for (int i = 0; i < getLayerCount(); i++){
//Test for collisions
if (getLayer(i).name.equals("Collisions") && collisionLayer == 0){
collisionLayer = getLayer(i).getTileID(newX / 32,
(newY + 8) / 32);
} else if (getLayer(i).name.equals("Water") && waterLayer == 0
&& GameClient.getInstance().getOurPlayer().getTrainerLevel() < 25){
waterLayer = getLayer(i).getTileID(newX / 32,
(newY + 8) / 32);
} else { //Test for ledges
if (p.getDirection() != Direction.Left
&& getLayer("LedgesLeft") != null){
ledgeLayer = getLayer("LedgesLeft").getTileID(newX / 32,
(newY + 8) / 32);
}
if (p.getDirection() != Direction.Right
&& getLayer("LedgesRight") != null
&& ledgeLayer == 0){
ledgeLayer = getLayer("LedgesRight").getTileID(newX / 32,
(newY + 8) / 32);
}
if (p.getDirection() != Direction.Down
&& getLayer("LedgesDown") != null
&& ledgeLayer == 0){
ledgeLayer = getLayer("LedgesDown").getTileID(newX / 32,
(newY + 8) / 32);
}
}
}
if (ledgeLayer + collisionLayer + waterLayer != 0)
return true;
/* Check NPCs */
for(int i = 0; i < m_mapMatrix.getPlayers().size(); i++) {
Player tmp = m_mapMatrix.getPlayers().get(i);
if(tmp.getUsername().equalsIgnoreCase("!NPC!") &&
tmp.getX() == newX && tmp.getY() == newY)
return true;
}
return false;
}
/**
* Returns true if a reflection should be drawn
*
* @param p
* @return
*/
public boolean shouldReflect(Player p) {
int newX = 0, newY = 0;
newX = p.getServerX();
newY = p.getServerY() + 32;
try {
if (getTileProperty(
getLayer("Water").getTileID(newX / 32, (newY + 8) / 32),
"Reflection", "").equalsIgnoreCase("true"))
return true;
if (getTileProperty(
getLayer("Walkable").getTileID(newX / 32, (newY + 8) / 32),
"Reflection", "").equalsIgnoreCase("true"))
return true;
for (int i = 0; i < getLayerCount(); i++) {
if (getTileProperty(
getLayer(i).getTileID(newX / 32, (newY + 8) / 32),
"Reflection", "").equalsIgnoreCase("true"))
return true;
}
} catch (Exception e) {
}
return false;
}
/**
* Returns true if the grass overlay should be drawn
*
* @param p
* @return
*/
public boolean isOnGrass(Player p) {
int newX = 0, newY = 0;
newX = p.getServerX();
newY = p.getServerY();
try {
if (getTileProperty(
getLayer("Walkable").getTileID(newX / 32, (newY + 8) / 32),
"Grass", "").equalsIgnoreCase("true"))
return true;
for (int i = 0; i < getLayerCount(); i++) {
if (getTileProperty(
getLayer(i).getTileID(newX / 32, (newY + 8) / 32),
"Grass", "").equalsIgnoreCase("true"))
return true;
}
} catch (Exception e) {
}
return false;
}
/**
* Returns true if a the previous grass overlay should be drawn
*
* @param p
* @return
*/
public boolean wasOnGrass(Player p) {
int newX = 0, newY = 0;
newX = p.getServerX();
newY = p.getServerY();
switch (p.getDirection()) {
case Up:
newY += 32;
break;
case Down:
newY -= 32;
break;
case Left:
newX += 32;
break;
case Right:
newX -= 32;
break;
}
try {
if (getTileProperty(
getLayer("Walkable").getTileID(newX / 32, (newY + 8) / 32),
"Grass", "").equalsIgnoreCase("true"))
return true;
for (int i = 0; i < getLayerCount(); i++) {
if (getTileProperty(
getLayer(i).getTileID(newX / 32, (newY + 8) / 32),
"Grass", "").equalsIgnoreCase("true"))
return true;
}
} catch (Exception e) {
}
return false;
}
/**
* Returns a layer by its index
*
* @param layer
* @return
*/
private Layer getLayer(int layer) {
return (Layer) layers.get(layer);
}
/**
* Returns a layer by its name
*
* @param layer
* @return
*/
private Layer getLayer(String layer) {
int idx = this.getLayerIndex(layer);
return (idx < 0 ? null : getLayer(idx));
}
/**
* Sets the y offset and recalibrates surrounding maps if calibrate is true
*
* @param offset
* @param calibrate
*/
public void setYOffset(int offset, boolean calibrate) {
m_yOffset = offset;
if (calibrate) {
// 0, 1 -- Left
ClientMap map = m_mapMatrix.getMap(m_mapX - 1, m_mapY);
if (map != null)
map.setYOffset(offset - getYOffsetModifier()
+ map.getYOffsetModifier(), false);
// 2, 1 -- Right
map = m_mapMatrix.getMap(m_mapX + 1, m_mapY);
if (map != null)
map.setYOffset(offset - getYOffsetModifier()
+ map.getYOffsetModifier(), false);
// 1, 0 -- Top
map = m_mapMatrix.getMap(m_mapX, m_mapY - 1);
if (map != null)
map.setYOffset(offset - map.getHeight() * 32, false);
// 1, 2 -- Bottom
map = m_mapMatrix.getMap(m_mapX, m_mapY + 1);
if (map != null) {
map.setYOffset(offset + getHeight() * 32, false);
}
// 2, 0 -- Upper Right
map = m_mapMatrix.getMap(m_mapX + 1, m_mapY - 1);
if (map != null) {
if (m_mapMatrix.getMap(2, 1) != null) { // The right map exists
map.setYOffset(m_mapMatrix.getMap(2, 1).m_yOffset
- map.getHeight() * 32, false);
} else if (m_mapMatrix.getMap(1, 0) != null) { // The top map
// exists
map.setYOffset(m_mapMatrix.getMap(1, 0).m_yOffset
- m_mapMatrix.getMap(1, 0).m_yOffsetModifier
+ map.getYOffsetModifier(), false);
} else { // Try in previous way
map.setYOffset(offset - map.getHeight() * 32, false);
}
}
// 0, 0 -- Upper Left
map = m_mapMatrix.getMap(m_mapX - 1, m_mapY - 1);
if (map != null) { // The top map exists
if (m_mapMatrix.getMap(0, 1) != null) { // The left map exists
map.setYOffset(m_mapMatrix.getMap(0, 1).m_yOffset
- map.getHeight() * 32, false);
} else if (m_mapMatrix.getMap(1, 0) != null) { // The top map
// exists
map.setYOffset(m_mapMatrix.getMap(1, 0).m_yOffset
- m_mapMatrix.getMap(1, 0).m_yOffsetModifier
+ map.getYOffsetModifier(), false);
} else { // Try in previous way
map.setYOffset(offset - map.getHeight() * 32, false);
}
}
// 2, 2 -- Lower Right
map = m_mapMatrix.getMap(m_mapX + 1, m_mapY + 1);
if (map != null) {
if (m_mapMatrix.getMap(1, 2) != null) { // The bottom map exists
map.setYOffset(m_mapMatrix.getMap(1, 2).m_yOffset
- m_mapMatrix.getMap(1, 2).m_yOffsetModifier
+ map.getYOffsetModifier(), false);
} else if (m_mapMatrix.getMap(2, 1) != null) { // The right map
// exists
map.setYOffset(m_mapMatrix.getMap(2, 1).m_yOffset
+ m_mapMatrix.getMap(2, 1).getHeight() * 32, false);
} else { // Try in previous way
System.out.println("else");
map.setYOffset(offset + getHeight() * 32, false);
}
}
// 0, 2 -- Lower Left
map = m_mapMatrix.getMap(m_mapX - 1, m_mapY + 1);
if (map != null) {
if (m_mapMatrix.getMap(0, 1) != null) { // The left map exists
map.setYOffset(m_mapMatrix.getMap(0, 1).m_yOffset
+ m_mapMatrix.getMap(0, 1).getHeight() * 32, false);
} else if (m_mapMatrix.getMap(1, 2) != null) { // The bottom map
// exists
map.setYOffset(m_mapMatrix.getMap(1, 2).m_yOffset
- m_mapMatrix.getMap(1, 2).m_yOffsetModifier
+ map.getYOffsetModifier(), false);
} else {
map.setYOffset(offset + getHeight() * 32, false);
}
}
}
}
/**
* Sets the x offset and recalibrates surrounding maps if calibrate is set
* to true
*
* @param offset
* @param calibrate
*/
public void setXOffset(int offset, boolean calibrate) {
m_xOffset = offset;
if (calibrate) {
// int thisX = (this.getXOffset() + (this.getWidth() * 32));
// 0, 1 -- Left
ClientMap map = m_mapMatrix.getMap(m_mapX - 1, m_mapY);
if (map != null)
map.setXOffset(offset - map.getWidth() * 32 - m_xOffsetModifier
+ map.getXOffsetModifier(), false);
// 2, 1 -- Right
map = m_mapMatrix.getMap(m_mapX + 1, m_mapY);
if (map != null)
map.setXOffset(offset + getWidth() * 32 - getXOffsetModifier()
+ map.getXOffsetModifier(), false);
// 1, 0 -- Up
map = m_mapMatrix.getMap(m_mapX, m_mapY - 1);
if (map != null)
map.setXOffset(offset - getXOffsetModifier()
+ map.getXOffsetModifier(), false);
// 1, 2 -- Down
map = m_mapMatrix.getMap(m_mapX, m_mapY + 1);
if (map != null)
map.setXOffset(offset - getXOffsetModifier()
+ map.getXOffsetModifier(), false);
// 0, 0 -- Upper Left
map = m_mapMatrix.getMap(m_mapX - 1, m_mapY - 1);
if (map != null) {
if (m_mapMatrix.getMap(0, 1) != null) { // The left map exists
map.setXOffset(m_mapMatrix.getMap(0, 1).m_xOffset
- m_mapMatrix.getMap(0, 1).m_xOffsetModifier
+ map.getXOffsetModifier(), false);
} else if (m_mapMatrix.getMap(1, 0) != null) { // The top map
// exists
map.setXOffset(m_mapMatrix.getMap(1, 0).m_xOffset
- map.getWidth() * 32
- m_mapMatrix.getMap(1, 0).m_xOffsetModifier
+ map.getXOffsetModifier(), false);
} else { // Try in previous way
map.setXOffset(offset - map.getWidth() * 32
- getXOffsetModifier() + map.getXOffsetModifier(),
false);
}
}
// 2, 0 -- Upper Right
map = m_mapMatrix.getMap(m_mapX + 1, m_mapY - 1);
if (map != null) {
if (m_mapMatrix.getMap(2, 1) != null) { // The right map exists
map.setXOffset(m_mapMatrix.getMap(2, 1).m_xOffset
- m_mapMatrix.getMap(2, 1).m_xOffsetModifier
+ map.getXOffsetModifier(), false);
} else if (m_mapMatrix.getMap(1, 0) != null) { // The top map
// exists
map.setXOffset(m_mapMatrix.getMap(1, 0).m_xOffset
+ m_mapMatrix.getMap(1, 0).getWidth() * 32
- m_mapMatrix.getMap(1, 0).m_xOffsetModifier
+ map.getXOffsetModifier(), false);
} else { // Try in previous way
map.setXOffset(offset - map.getWidth() * 32
- getXOffsetModifier() + map.getXOffsetModifier(),
false);
}
}
// 2, 2 -- Lower Right
map = m_mapMatrix.getMap(m_mapX + 1, m_mapY + 1);
if (map != null) {
if (m_mapMatrix.getMap(2, 1) != null) { // The right map exists
map.setXOffset(m_mapMatrix.getMap(2, 1).m_xOffset
- m_mapMatrix.getMap(2, 1).m_xOffsetModifier
+ map.getXOffsetModifier(), false);
} else if (m_mapMatrix.getMap(1, 2) != null) { // The Bottom map
// exists
map.setXOffset(m_mapMatrix.getMap(1, 2).m_xOffset
+ m_mapMatrix.getMap(1, 2).getWidth() * 32
- m_mapMatrix.getMap(1, 2).m_xOffsetModifier
+ map.getXOffsetModifier(), false);
} else { // Try in previous way
map.setXOffset(offset + getWidth() * 32
- getXOffsetModifier() + map.getXOffsetModifier(),
false);
}
}
// 0, 2 -- Lower Left
map = m_mapMatrix.getMap(m_mapX - 1, m_mapY + 1);
if (map != null) {
if (m_mapMatrix.getMap(0, 1) != null) { // The left map exists
map.setXOffset(m_mapMatrix.getMap(0, 1).m_xOffset
- m_mapMatrix.getMap(0, 1).m_xOffsetModifier
+ map.getXOffsetModifier(), false);
} else if (m_mapMatrix.getMap(1, 2) != null) { // The bottom map
// exists
map.setXOffset(m_mapMatrix.getMap(1, 2).m_xOffset
- map.getWidth() * 32
- m_mapMatrix.getMap(1, 2).m_xOffsetModifier
+ map.getXOffsetModifier(), false);
} else { // Try in previous way
map.setXOffset(offset + getWidth() * 32
- getXOffsetModifier() + map.getXOffsetModifier(),
false);
}
}
}
}
@Override
public void render(int x, int y, int sx, int sy, int width, int height,
boolean lineByLine) {
for (int ty = 0; ty < height; ty++) {
for (int i = 0; i < layers.size(); i++) {
Layer layer = (Layer) layers.get(i);
if (!m_isCurrent) {
layer.render(x, y, sx, sy, width, ty, lineByLine,
tileWidth, tileHeight);
} else if (!layer.name.equalsIgnoreCase("WalkBehind")) {
layer.render(x, y, sx, sy, width, ty, lineByLine,
tileWidth, tileHeight);
}
}
}
}
/**
* Renders the player, water reflections, grass overlays, and the WalkBehind
* layer.
*
* @param g
*/
public void renderTop(Graphics g) {
synchronized (m_mapMatrix.getPlayers()) {
Player p;
Iterator<Player> it = m_mapMatrix.getPlayers().iterator();
while (it.hasNext()) {
p = it.next();
ClientMap m_curMap = m_mapMatrix.getCurrentMap();
int m_xOffset = m_curMap.getXOffset();
int m_yOffset = m_curMap.getYOffset();
if (p != null && p.getSprite() != 0
&& (p.getCurrentImage() != null)) {
// Draw the player
p.getCurrentImage().draw(m_xOffset + p.getX() - 4,
m_yOffset + p.getY());
if (m_curMap.shouldReflect(p)) {
// If there's a reflection, flip the player's image, set
// his alpha so its more translucent, and then draw it.
Image m_reflection = p.getCurrentImage()
.getFlippedCopy(false, true);
m_reflection.setAlpha((float) 0.05);
if (p.getSprite() != -1)
m_reflection.draw(m_xOffset + p.getX() - 4,
m_yOffset + p.getY() + 32);
else {
m_reflection.draw(m_xOffset + p.getX() - 4,
m_yOffset + p.getY() + 8);
}
}
if (m_curMap.wasOnGrass(p) && m_curMap.isOnGrass(p)) {
switch (p.getDirection()) {
case Up:
m_grassOverlay.draw(m_xOffset + p.getServerX(),
m_yOffset + p.getServerY() + 32 + 8);
break;
case Left:
m_grassOverlay.copy().draw(
m_xOffset + p.getServerX() + 32,
m_yOffset + p.getServerY() + 8);
break;
case Right:
m_grassOverlay.copy().draw(
m_xOffset + p.getServerX() - 32,
m_yOffset + p.getServerY() + 8);
break;
}
}
if (m_curMap.isOnGrass(p) && p.getY() <= p.getServerY()) {
m_grassOverlay.draw(m_xOffset + p.getServerX(),
m_yOffset + p.getServerY() + 9);
}
// Draw the walk behind layer
g.scale(2, 2);
try{
for (int i = 0; i < getLayer("WalkBehind").height; i++) {
getLayer("WalkBehind").render(
getXOffset() / 2,
getYOffset() / 2,
0,
0,
(int) (GameClient.getInstance().getDisplay()
.getWidth() - getXOffset()) / 32 + 32,
i, false, 16, 16);
}
} catch (Exception e) {}
g.resetTransform();
// Draw player names
if(!p.getUsername().equalsIgnoreCase("!NPC!"))
g.drawString(p.getUsername(), m_xOffset
+ (p.getX() - (g.getFont()
.getWidth(p.getUsername()) / 2)) + 16,
m_yOffset + p.getY() - 36);
}
}
}
}
/**
* Returns the map's name
*
* @return the map's name
*/
public String getName() {
return m_name;
}
/**
* Sets the map's name
*
* @param name
*/
public void setName(String name) {
m_name = name;
}
public int getMapX() {
return m_mapX;
}
public int getMapY() {
return m_mapY;
}
}