/*
* This file is part of Spoutcraft.
*
* Copyright (c) 2011 SpoutcraftDev <http://spoutcraft.org/>
* Spoutcraft is licensed under the GNU Lesser General Public License.
*
* Spoutcraft is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Spoutcraft is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.spoutcraft.client.gui.minimap;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.util.LinkedList;
public class Map {
/**
* Used to track world changes and force a rerender when the world
* changes.
*/
public String lastRenderedWorld = "";
/**
* Used to track dimension changes and force a rerender when the dimension
* changes.
*/
public int lastRenderedDimension = 0;
/**
* X coordinate of the player on last render
*/
private double playerX = Integer.MAX_VALUE;
/**
* Z coordinate of the player on last render
*/
private double playerZ = Integer.MAX_VALUE;
/**
* Zoom level currently rendering at at - used in case zoom changes in the
* middle of rendering a map frame
*/
public int zoom = -1;
public boolean square;
/**
* How many blocks to x+ to shift the map rendering from the origin of the
* center chunk
*/
public int originOffsetX = 0;
/**
* How many blocks to z+ to shift the map rendering from the origin of the
* center chunk
*/
public int originOffsetY = 0;
public int timer = 0;
public int imageSize = 276 * 2;
public int updatedist = 4;
// Denotes the width or the diameter of a map
public static final int ZOOM_2 = 256;
public static final int ZOOM_1 = 128;
public static final int ZOOM_0 = 64;
public int renderSize = 256;
public int renderOff = 128; // Used instead of dividing renderSize by two
/**
* Map image to which the map is rendered to.
*/
public final ImageManager colorimg;
public final ImageManager heightimg;
public final ImageManager lightimg;
public LinkedList<WatchedEntity> watchedEntities = new LinkedList<WatchedEntity>();
public Map(int size) {
imageSize = size;
colorimg = new ImageManager(imageSize, imageSize, BufferedImage.TYPE_INT_ARGB);
heightimg = new ImageManager(imageSize, imageSize, BufferedImage.TYPE_INT_ARGB);
lightimg = new ImageManager(imageSize, imageSize, BufferedImage.TYPE_INT_ARGB);
}
public Map() {
this(276 * 2);
}
/**
* Take an array index and wrap it to the size of the array, properly
* dealing with negative values
* @param index index to wrap
* @param arraysize size of array to wrap to
* @return wrapped index
*/
private final int wrapIndex(int index, int arraysize) {
if (index < 0) {
return arraysize + ((index+1) % arraysize) - 1;
} else {
return index % arraysize;
}
}
public final int toImageX(int worldz) {
return worldz; // return wrapIndex((int) (( -(worldz - playerZ)) + originOffsetX), imageSize);
}
public final int toImageY(int worldx) {
return worldx; // return wrapIndex( (int) ((worldx - playerX) + originOffsetY), imageSize);
}
public void setColorPixel(int worldx, int worldz, int color24) {
colorimg.setRGB(toImageX(worldz), toImageY(worldx), color24);
}
public void clearColorPixel(int worldx, int worldz) {
colorimg.setARGB(toImageX(worldz), toImageY(worldx), 0);
}
public void setHeightPixel(int worldx, int worldz, int height) {
heightimg.setRGB(toImageX(worldz), toImageY(worldx), height | height << 8 | height << 16);
}
public void setLightPixel(int worldx, int worldz, int light) {
lightimg.setRGB(toImageX(worldz), toImageY(worldx), light | light << 8 | light << 16);
}
public void loadColorImage() {
colorimg.loadGLImage();
}
public void loadHeightImage() {
heightimg.loadGLImage();
}
public void loadLightImage() {
lightimg.loadGLImage();
}
public Raster getColorRaster() {
return colorimg.image.getRaster();
}
public void clear() {
for (int i = 0; i < imageSize; i++) {
for (int j = 0; j < imageSize; j++) {
colorimg.setARGB(i, j, 0);
lightimg.setARGB(i, j, 0);
heightimg.setARGB(i, j, 0);
}
}
}
public void update(double playerx, double playerz) {
this.playerX = playerx;
this.playerZ = playerz;
originOffsetX = wrapIndex((int) -this.playerZ, imageSize);
originOffsetY = wrapIndex((int) this.playerX, imageSize);
}
public double getPlayerX() {
return playerX;
}
public double getPlayerZ() {
return playerZ;
}
public boolean isDirty(double newPlayerX, double newPlayerZ) {
return Math.abs(playerX - newPlayerX) > updatedist || Math.abs(playerZ - newPlayerZ) > updatedist || timer > 300 || zoom != MinimapConfig.getInstance().getZoom() || square != MinimapConfig.getInstance().isSquare();
}
public float getRenderScale() {
float displaydist = (float) (Math.pow(2, zoom) * 32);
return (float)imageSize / displaydist;
}
/**
* @return
*/
public double getCurrOffsetX(double playerZ) {
double wrapped = wrapIndex(((int) -playerZ), imageSize);
double leftover = 0; // playerZ - ((double)(int)playerZ);
return (wrapped+leftover)/2;
}
public double getCurrOffsetY(double playerX) {
double wrapped = wrapIndex(((int) playerX), imageSize);
double leftover = 0; // playerX - ((double)(int)playerX);
return (wrapped+leftover)/2;
}
}