package common.ui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JPanel;
import common.CommonUtils;
import common.Direction;
import common.PubRoom;
import common.RoomType;
public class GameMap extends JPanel {
private static final long serialVersionUID = 3833468396569506614L;
private static final int ROOM_SIZE = 15;
private static final int CELL_SIZE = 25;
private static final int OVAL_SIZE = 9;
private static final int TRACKING_OVAL_SIZE = 13;
private static final int BORDER_SIZE = (CELL_SIZE - ROOM_SIZE) / 2;
private static final int OVAL_BORDER_SIZE = (CELL_SIZE - OVAL_SIZE) / 2;
private static final int TRACKING_OVAL_BORDER_SIZE = (CELL_SIZE - TRACKING_OVAL_SIZE) / 2;
private static final Color LINE_COLOR = new Color(142, 105, 62);
private static final int MAP_BORDER = 100;
private int minX;
private int minY;
private int maxX;
private int maxY;
private Map<Point,PubRoom> rooms = new HashMap<Point,PubRoom>();
private Point currentLocation;
private String areaName;
private Map<String,Color> areaColors = new HashMap<String,Color>();
private Map<Integer,Point> roomForPlayer;
private Map<Point,Integer> countForRoom;
public GameMap() {
setBackground(Color.white);
areaColors.put("cshome", new Color(200, 255, 200));
areaColors.put("exile", Color.red);
}
public void init(String newAreaName, int newMinX, int newMinY, int newMaxX, int newMaxY, Map<Point,PubRoom> newRooms) {
roomForPlayer = new HashMap<Integer,Point>();
countForRoom = new HashMap<Point,Integer>();
this.areaName = newAreaName;
this.minX = newMinX;
this.minY = newMinY;
this.maxX = newMaxX;
this.maxY = newMaxY;
this.rooms = newRooms;
Color color = areaColors.get(areaName);
if (color != null) {
setBackground(color);
}
else {
setBackground(Color.white);
}
setSizes();
repaint();
}
private void setSizes() {
int width = (maxX - minX + 1) * CELL_SIZE + MAP_BORDER * 2;
int height = (maxY - minY + 1) * CELL_SIZE + MAP_BORDER * 2;
setMinimumSize(new Dimension(width, height));
setMaximumSize(new Dimension(width, height));
setPreferredSize(new Dimension(width, height));
setSize(new Dimension(width, height));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setFont(g2.getFont().deriveFont(Font.BOLD, 10.0f));
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
Point p = new Point(x, y);
PubRoom room = rooms.get(p);
if (room != null) {
int dx = x - minX;
int dy = y - minY;
g2.setColor(room.roomType.getColor());
g2.fillRect(dx * CELL_SIZE + BORDER_SIZE + MAP_BORDER,
dy * CELL_SIZE + BORDER_SIZE + MAP_BORDER,
ROOM_SIZE, ROOM_SIZE);
g2.setColor(LINE_COLOR);
g2.drawRect(dx * CELL_SIZE + BORDER_SIZE + MAP_BORDER,
dy * CELL_SIZE + BORDER_SIZE + MAP_BORDER,
ROOM_SIZE, ROOM_SIZE);
if (currentLocation != null &&
x == currentLocation.x &&
y == currentLocation.y) {
g2.setColor(Color.blue);
g2.fillOval(dx * CELL_SIZE +
OVAL_BORDER_SIZE +
MAP_BORDER,
dy * CELL_SIZE +
OVAL_BORDER_SIZE +
MAP_BORDER,
OVAL_SIZE,
OVAL_SIZE);
g2.setColor(Color.white);
g2.drawOval(dx * CELL_SIZE +
OVAL_BORDER_SIZE +
MAP_BORDER,
dy * CELL_SIZE +
OVAL_BORDER_SIZE +
MAP_BORDER,
OVAL_SIZE,
OVAL_SIZE);
}
else {
Integer count = countForRoom.get(p);
if (count != null) {
int rx = dx * CELL_SIZE + TRACKING_OVAL_BORDER_SIZE + MAP_BORDER;
int ry = dy * CELL_SIZE + TRACKING_OVAL_BORDER_SIZE + MAP_BORDER;
g2.setColor(Color.white);
g2.fillOval(rx, ry, TRACKING_OVAL_SIZE, TRACKING_OVAL_SIZE);
g2.setColor(Color.darkGray);
g2.drawOval(rx, ry, TRACKING_OVAL_SIZE, TRACKING_OVAL_SIZE);
String s = count.toString();
FontMetrics metrics = g2.getFontMetrics();
Rectangle2D bounds = metrics.getStringBounds(s, g2);
bounds.setRect(
bounds.getX(),
bounds.getY(),
bounds.getWidth(),
metrics.getAscent());
double sx = (CELL_SIZE - bounds.getWidth()) / 2.0;
double sy = (CELL_SIZE - bounds.getHeight()) / 2.0;
sy += bounds.getHeight();
sx += dx * CELL_SIZE + MAP_BORDER;
sy += dy * CELL_SIZE + MAP_BORDER;
g2.setColor(Color.black);
g2.drawString(s, (int) sx, (int) sy);
}
}
g2.setColor(LINE_COLOR);
RoomType northType = roomType(x, y, Direction.NORTH);
RoomType northeastType = roomType(x, y, Direction.NORTHEAST);
RoomType eastType = roomType(x, y, Direction.EAST);
RoomType southeastType = roomType(x, y, Direction.SOUTHEAST);
RoomType southType = roomType(x, y, Direction.SOUTH);
RoomType southwestType = roomType(x, y, Direction.SOUTHWEST);
RoomType westType = roomType(x, y, Direction.WEST);
RoomType northwestType = roomType(x, y, Direction.NORTHWEST);
boolean north = northType != null;
boolean northeast = northeastType != null;
boolean east = eastType != null;
boolean southeast = southeastType != null;
boolean south = southType != null;
boolean southwest = southwestType != null;
boolean west = westType != null;
boolean northwest = northwestType != null;
if (north) {
g2.drawLine(dx * CELL_SIZE + CELL_SIZE / 2 + MAP_BORDER,
dy * CELL_SIZE + BORDER_SIZE + MAP_BORDER,
dx * CELL_SIZE + CELL_SIZE / 2 + MAP_BORDER,
dy * CELL_SIZE + MAP_BORDER);
}
if (northeast && (CommonUtils.isConnected(room.roomType, northeastType) || !(north ^ east))) {
g2.drawLine(dx * CELL_SIZE + CELL_SIZE - BORDER_SIZE + MAP_BORDER,
dy * CELL_SIZE + BORDER_SIZE + MAP_BORDER,
dx * CELL_SIZE + CELL_SIZE + MAP_BORDER,
dy * CELL_SIZE + MAP_BORDER);
}
if (east) {
g2.drawLine(
dx * CELL_SIZE + CELL_SIZE - BORDER_SIZE + MAP_BORDER,
dy * CELL_SIZE + CELL_SIZE / 2 + MAP_BORDER,
dx * CELL_SIZE + CELL_SIZE + MAP_BORDER,
dy * CELL_SIZE + CELL_SIZE / 2 + MAP_BORDER);
}
if (southeast && (CommonUtils.isConnected(room.roomType, southeastType) || !(south ^ east))) {
g2.drawLine(
dx * CELL_SIZE + CELL_SIZE - BORDER_SIZE + MAP_BORDER,
dy * CELL_SIZE + CELL_SIZE - BORDER_SIZE + MAP_BORDER,
dx * CELL_SIZE + CELL_SIZE + MAP_BORDER,
dy * CELL_SIZE + CELL_SIZE + MAP_BORDER);
}
if (south) {
g2.drawLine(dx * CELL_SIZE + CELL_SIZE / 2 + MAP_BORDER,
dy * CELL_SIZE + CELL_SIZE - BORDER_SIZE + MAP_BORDER,
dx * CELL_SIZE + CELL_SIZE / 2 + MAP_BORDER,
dy * CELL_SIZE + CELL_SIZE + MAP_BORDER);
}
if (southwest && (CommonUtils.isConnected(room.roomType, southwestType) || !(south ^ west))) {
g2.drawLine(
dx * CELL_SIZE + BORDER_SIZE + MAP_BORDER,
dy * CELL_SIZE + CELL_SIZE - BORDER_SIZE + MAP_BORDER,
dx * CELL_SIZE + MAP_BORDER,
dy * CELL_SIZE + CELL_SIZE + MAP_BORDER);
}
if (west) {
g2.drawLine(
dx * CELL_SIZE + BORDER_SIZE + MAP_BORDER,
dy * CELL_SIZE + CELL_SIZE / 2 + MAP_BORDER,
dx * CELL_SIZE + MAP_BORDER,
dy * CELL_SIZE + CELL_SIZE / 2 + MAP_BORDER);
}
if (northwest && (CommonUtils.isConnected(room.roomType, northwestType) || !(north ^ west))) {
g2.drawLine(dx * CELL_SIZE + BORDER_SIZE + MAP_BORDER,
dy * CELL_SIZE + BORDER_SIZE + MAP_BORDER,
dx * CELL_SIZE + MAP_BORDER,
dy * CELL_SIZE + MAP_BORDER);
}
}
}
}
}
private RoomType roomType(int x, int y, Direction direction) {
Point offsets = direction.getOffsets();
Point p = new Point(x + offsets.x, y + offsets.y);
PubRoom room = rooms.get(p);
return room == null ? null : room.roomType;
}
public void setCurrentRoom(Point p) {
currentLocation = p;
PubRoom room = rooms.get(p);
GameClient.setRoomName(room.name);
centerCurrentRoom();
}
public void centerCurrentRoom() {
Rectangle rect = getVisibleRect();
rect.x = (currentLocation.x - minX) * CELL_SIZE + CELL_SIZE / 2 - rect.width / 2 + MAP_BORDER;
rect.y = (currentLocation.y - minY) * CELL_SIZE + CELL_SIZE / 2 - rect.height / 2 + MAP_BORDER;
if (rect.x < 0) {
rect.x = 0;
}
if (rect.y < 0) {
rect.y = 0;
}
scrollRectToVisible(rect);
repaint();
}
public void roomUpdated(PubRoom room) {
Point p = new Point(room.x, room.y);
rooms.put(p, room);
minX = Math.min(minX, room.x);
minY = Math.min(minY, room.y);
maxX = Math.max(maxX, room.x);
maxY = Math.max(maxY, room.y);
setSizes();
repaint();
if (p.equals(currentLocation)) {
GameClient.setRoomName(room.name);
}
}
public void roomDestroyed(Point p) {
rooms.remove(p);
repaint();
}
public void track(int player, Point room) {
Point oldRoom = roomForPlayer.remove(player);
if (oldRoom != null) {
int count = countForRoom.get(oldRoom) - 1;
if (count == 0) {
countForRoom.remove(oldRoom);
}
else {
countForRoom.put(oldRoom, count);
}
}
if (room != null) {
roomForPlayer.put(player, room);
Integer count = countForRoom.get(room);
if (count == null) {
count = 0;
}
countForRoom.put(room, count + 1);
}
repaint();
}
}