Hex.java
/*
* $RCSfile: Hex.java,v $
* $Id: Hex.java,v 1.6 1998/11/30 02:21:07 devnull Exp $
* by Lee Wilson, http://www.ad1440.net/~devnull
* Development started on 1998 10 01
* (c) Devnull Software, LLC. (http://www.devnullsoftware.com)
*/
package com.devnullsoftware.javaterrain;
/*
* The Hex class is the basic element in the terrain. It contains the
* terrains elevation, the amount of water in the hex, the amount
* of water generated in the hex, etc
*
* @author Lee Wilson (devnull@ad1440.net)
* @version 1.0
*/
import java.awt.*;
public class Hex {
//-------------------------------------------------------------------
// Global Constants
//
public static final byte N = 0;
public static final byte NE = 1;
public static final byte SE = 2;
public static final byte S = 3;
public static final byte SW = 4;
public static final byte NW = 5;
public static final String [] sShortDirectionString = {
"N","NE","SE","S","SW","NW"
};
public static final String [] sLongDirectionString = {
"North","NorthEast","SouthEast","South","SouthWest","NorthWest"
};
public static final byte [] BW_DIRS = {
1,2,4,8,16,32
};
public static final byte WIND_N = 1;
public static final byte WIND_S = 2;
public static final byte WIND_E = 4;
public static final byte WIND_W = 8;
public static final byte PRESSURE_LOW = 1;
public static final byte PRESSURE_HIGH = 2;
public static final byte PRESSURE_HEQ = 3;
public static final byte CLIMATE_TUNDRA = 1;
public static final byte CLIMATE_STEPPE = 2;
public static final byte CLIMATE_DECIDUOUS = 3;
public static final byte CLIMATE_DESERT = 4;
public static final byte CLIMATE_SAVANNAH = 5;
public static final byte CLIMATE_JUNGLE = 6;
public static final byte CLIMATE_SWAMP = 7;
public static final byte CLIMATE_OCEAN = 8;
public static final byte CLIMATE_OCEANICE = 9;
public static final byte CLIMATE_PRAIRIE = 10;
public static final byte NUM_TERRAIN = 14;
public static final byte TERRAIN_NOTYPE = 0;
public static final byte TERRAIN_DEEPOCEAN = 1;
public static final byte TERRAIN_OCEAN = 2;
public static final byte TERRAIN_MOUNTAINS = 3;
public static final byte TERRAIN_IMPASSABLEMOUNTAINS = 4;
public static final byte TERRAIN_VOLCANO = 5;
public static final byte TERRAIN_ICE = 6;
public static final byte TERRAIN_TUNDRA = 7;
public static final byte TERRAIN_STEPPE = 8;
public static final byte TERRAIN_PRAIRIE = 9;
public static final byte TERRAIN_SAVANNAH = 10;
public static final byte TERRAIN_FOREST = 11;
public static final byte TERRAIN_JUNGLE = 12;
public static final byte TERRAIN_SWAMP = 13;
public static final byte TERRAIN_DESERT = 14;
public static final String [] sTerrainLongString = {
"NONE",
"DeepOcean", "Ocean", "Mountains", "ImpassableMountains", "Volcano",
"Ice", "Tundra", "Steppe", "Prairie", "Savannah",
"Forest", "Jungle", "Swamp", "Desert",
};
public static final String [] sTerrainShortString = {
"!",
" ", " ", "^", "M", "V",
"I", "#", "-","=", "+",
"*", "&", "Y", "D"
};
public static final Color [] COLOR_TERRAIN = {
Color.black,
Color.blue,
Color.blue.darker(),
Color.gray,
Color.darkGray,
Color.red,
Color.white,
Color.lightGray,
Color.green.brighter(),
Color.green,
Color.orange.brighter().brighter(),
Color.green.darker(),
Color.yellow.darker().darker(),
Color.magenta,
Color.orange
};
public static Image [] pScaledImage;
public static final Color [] COLOR_TEMPERATURE = {
Color.blue, Color.green, Color.yellow, Color.red
};
public static final Color [] COLOR_RAINFALL = {
Color.red, Color.magenta, Color.orange, Color.green, Color.blue
};
public static final Color [] COLOR_ELEVATION = {
new Color(0.0f, 0.0f, 0.0f),
new Color(0.1f, 0.1f, 0.1f),
new Color(0.2f, 0.2f, 0.2f),
new Color(0.3f, 0.3f, 0.3f),
new Color(0.4f, 0.4f, 0.4f),
new Color(0.5f, 0.5f, 0.5f),
new Color(0.6f, 0.6f, 0.6f),
new Color(0.7f, 0.7f, 0.7f),
new Color(0.8f, 0.8f, 0.8f),
new Color(0.9f, 0.9f, 0.9f),
new Color(1.0f, 1.0f, 1.0f)
};
public static final byte GOODIE_NONE = 0;
public static final byte GOODIE_GEMS = 1;
public static final byte GOODIE_QUARX = 2;
public static final byte GOODIE_CRYSX = 3;
public static final byte GOODIE_IRON = 4;
public static final byte GOODIE_COAL = 5;
public static final byte GOODIE_SILVER = 6;
public static final byte GOODIE_GOLD = 7;
public static final byte GOODIE_MITHRIL = 8;
public static final byte GOODIE_ADAMANTIUM = 9;
public static final byte GOODIE_WILDGAME = 10;
public static final byte GOODIE_NIGHTSHADE = 11;
public static final String [] sGoodieStrings = {
"None",
"Gems", "Quarx", "Crysx", "Iron", "Coal",
"Silver", "Gold", "Mithril", "Adamantium", "Wild Game",
"Nightshade"
};
//-------------------------------------------------------------------
// Instance Variables
//
private String sName = null;
private int iIDNum;
private int iX;
private int iY;
private float fElevation = 0.0f;
private float [] fTemperature;
private float [] fScaledTemperature;
private byte [] iPressure;
private short [] iWind;
private short [] iRainfall;
private byte iClimate;
private byte iTerrainType = TERRAIN_NOTYPE;
private Hex [] pNeighbors;
private byte iShoreline;
private byte iRiver;
private byte iGoodie;
private Map pMap;
//---------------------------------------------------------------------------
// Constructors
//
Hex(int x, int y, String sName, Map pMap) {
this.iX = x;
this.iY = y;
this.iIDNum = (y * pMap.pParams.iDim) + x;
this.sName = sName;
this.pMap = pMap;
init ();
};
private void init () {
pNeighbors = new Hex[6];
fTemperature = new float [pMap.pParams.iNumSeasons];
fScaledTemperature = new float [pMap.pParams.iNumSeasons];
iPressure = new byte [pMap.pParams.iNumSeasons];
iWind = new short [pMap.pParams.iNumSeasons];
iRainfall = new short [pMap.pParams.iNumSeasons];
}
//---------------------------------------------------------------------------
// Accessors and Mutators
//
public String toString () {
return (sName+": ("+getElevation()+","+sTerrainLongString[getTerrainType()]+")");
}
public String getName () {
return sName;
}
public void setName (String newName) {
if (newName != null && !newName.equals("")) {
sName = newName;
}
}
public byte getTerrainType () {
return iTerrainType;
}
public void setTerrainType (byte newTerrainType) {
if (newTerrainType >= 0 && newTerrainType <= NUM_TERRAIN) {
iTerrainType = newTerrainType;
}
}
public Hex getNeighbor (int iDirection) {
if (iDirection >= 0 && iDirection < 6) {
return pNeighbors[iDirection];
}
return null;
}
public void setNeighbor (int iDirection, Hex pHex) {
if (iDirection >= 0 && iDirection < 6) {
pNeighbors[iDirection] = pHex;
}
}
public float getElevation() {
return (fElevation);
};
public void setElevation (float dValue) {
fElevation = dValue;
};
public float getTemperature(int iSeason) {
if (iSeason >= 0 && iSeason < pMap.pParams.iNumSeasons) {
return (fTemperature[iSeason]);
}
else {
return 0.0f;
}
}
public void setTemperature (int iSeason, float fTemp) {
if (iSeason >= 0 && iSeason < pMap.pParams.iNumSeasons) {
fTemperature[iSeason] = fTemp;
}
}
public float getAvgTemperatureF () {
float fAvgTemp = 0.0f;
for (int i = 0; i < pMap.pParams.iNumSeasons; i++) {
fAvgTemp += getTemperature(i);
}
fAvgTemp /= pMap.pParams.iNumSeasons;
fAvgTemp = ((fAvgTemp / 10.0f) - 273.0f) * 1.8f + 32.0f;
return fAvgTemp;
}
public float getScaledTemperature(int iSeason) {
if (iSeason >= 0 && iSeason < pMap.pParams.iNumSeasons) {
return (fScaledTemperature[iSeason]);
}
else {
return 0.0f;
}
}
public void setScaledTemperature (int iSeason, float fTemp) {
if (iSeason >= 0 && iSeason < pMap.pParams.iNumSeasons) {
fScaledTemperature[iSeason] = fTemp;
}
}
public byte getPressure(int iSeason) {
if (iSeason >= 0 && iSeason < pMap.pParams.iNumSeasons) {
return (iPressure[iSeason]);
}
else {
return 0;
}
}
public void setPressure (int iSeason, byte bPres) {
if (iSeason >= 0 && iSeason < pMap.pParams.iNumSeasons) {
iPressure[iSeason] = bPres;
}
}
public short getWind(int iSeason) {
if (iSeason >= 0 && iSeason < pMap.pParams.iNumSeasons) {
return (iWind[iSeason]);
}
else {
return 0;
}
}
public void setWind (int iSeason, short iW) {
if (iSeason >= 0 && iSeason < pMap.pParams.iNumSeasons) {
iWind[iSeason] = iW;
}
}
public short getRainfall(int iSeason) {
if (iSeason >= 0 && iSeason < pMap.pParams.iNumSeasons) {
return (iRainfall[iSeason]);
}
else {
return 0;
}
}
public float getAvgRainfall () {
float fAvgRain = 0.0f;
for (int i = 0; i < pMap.pParams.iNumSeasons; i++) {
fAvgRain += getRainfall(i);
}
fAvgRain /= pMap.pParams.iNumSeasons;
return fAvgRain;
}
public void setRainfall (int iSeason, short iRF) {
if (iSeason >= 0 && iSeason < pMap.pParams.iNumSeasons) {
iRainfall[iSeason] = iRF;
}
}
public byte getClimate() {
return (iClimate);
}
public void setClimate (byte iClim) {
iClimate = iClim;
}
public int getX () {
return iX;
}
public int getY () {
return iY;
}
public int getIDNum () {
return iIDNum;
}
public boolean isWater () {
boolean bWater;
switch (getTerrainType()) {
case TERRAIN_DEEPOCEAN:
case TERRAIN_OCEAN:
bWater = true;
break;
default:
bWater = false;
break;
}
return bWater;
}
public boolean isLand () {
boolean bLand;
switch (getTerrainType()) {
case TERRAIN_DEEPOCEAN:
case TERRAIN_OCEAN:
bLand = false;
break;
default:
bLand = true;
break;
}
return bLand;
}
public void clearShorelines () {
iShoreline = 0;
}
public void setShoreline (byte iDir, boolean value) {
if (value) {
iShoreline |= iDir;
}
else {
iShoreline ^= iDir;
}
}
public boolean isShoreline (byte iDir) {
return ((iShoreline & iDir) > 0);
}
public byte getGoodie() {
return (iGoodie);
}
public void setGoodie (byte iGood) {
iGoodie = iGood;
}
//-------------------------------------------------------------------
// Security
//
//---------------------------------------------------------------------------
// Methods
//
public static void rescaleImages(Image [] pImages, int iZoomLevel) {
if (pImages == null) {
return;
}
Rectangle pRect = new Rectangle (MapCanvas.HEXSIZE[iZoomLevel],
MapCanvas.HEXSIZE[iZoomLevel]);
MediaTracker pTracker = new MediaTracker (Main.pThisApplet);
for (int i = 0; i < pImages.length; i++) {
if (pImages[i] != null) {
pScaledImage[i] = pImages[i].getScaledInstance(pRect.width, pRect.height, Image.SCALE_FAST);
pTracker.addImage(pScaledImage[i], 0);
}
else {
pScaledImage[i] = null;
}
}
try {
pTracker.waitForID(0);
}
catch (InterruptedException e) {
}
}
public void paintHex (Graphics g, Polygon pArea,
int iZoomLevel, int iViewType) {
int iCounter;
float fAvgTemp, fAvgRain, fElevation;
switch (iViewType) {
case MapCanvas.VIEW_TERRAIN:
if (pScaledImage[getTerrainType()] != null) {
Graphics pGraphics = g.create();
pGraphics.setClip(pArea);
Rectangle pRect = pArea.getBounds();
pGraphics.translate(pRect.x, pRect.y);
pGraphics.drawImage(pScaledImage[getTerrainType()],
0,0,null);
pGraphics.dispose();
}
else {
g.setColor (COLOR_TERRAIN[getTerrainType()]);
g.fillPolygon (pArea);
}
break;
case MapCanvas.VIEW_TEMPERATURE:
iCounter = 0;
fAvgTemp = getAvgTemperatureF();
while ( iCounter < (pMap.pParams.TEMPCUT.length-1)
&& (int)fAvgTemp > pMap.pParams.TEMPCUT[iCounter]) {
iCounter++;
}
g.setColor (COLOR_TEMPERATURE[iCounter]);
g.fillPolygon (pArea);
break;
case MapCanvas.VIEW_RAINFALL:
iCounter = 0;
fAvgRain = getAvgRainfall();
while ( iCounter < (pMap.pParams.RAINCUT.length-1)
&& (int)fAvgRain > pMap.pParams.RAINCUT[iCounter]) {
iCounter++;
}
g.setColor (COLOR_RAINFALL[iCounter]);
g.fillPolygon (pArea);
break;
case MapCanvas.VIEW_ELEVATION:
fElevation = getElevation();
iCounter = 0;
while ( iCounter < (pMap.pParams.ELEVATIONCUT.length-1)
&& fElevation > pMap.pParams.ELEVATIONCUT[iCounter]) {
iCounter++;
}
g.setColor (COLOR_ELEVATION[iCounter]);
g.fillPolygon (pArea);
break;
default:
break;
}
g.setColor(Color.white);
switch (iZoomLevel) {
case 4:
case 3:
int x = (pArea.xpoints[0] + pArea.xpoints[1]) / 2;
int y = ((pArea.ypoints[1] + pArea.ypoints[3]) / 2) + 4;
g.drawString(Hex.sTerrainShortString[getTerrainType()]+iGoodie, x, y);
break;
default:
break;
}
}
}