package com.drakulo.games.ais.ui;
import java.util.ArrayList;
import java.util.List;
import org.newdawn.slick.tiled.TiledMap;
import com.drakulo.games.ais.core.Colony;
import com.drakulo.games.ais.core.GameData;
import com.drakulo.games.ais.core.building.Building;
import com.drakulo.games.ais.core.building.BuildingType;
public final class TileHelper {
public static final int ACCESS_LAYER = 1;
public static final int DECO_LAYER = 0;
public static final int DEFAULT_TILE = 2;
public static final int BUILDABLE_TILE = 3;
/**
* Tests if a tile is buildable according to the building type. Buildings
* can only be built around a road. Roads can be built around other roads
* and buildings
*
* @param x
* X coordinate of the tile
* @param y
* Y coordinate of the tile
* @param type
* the building type
* @return true if the building type can be built on the given tile
*/
public static boolean tileIsBuildable(int x, int y, BuildingType type) {
TiledMap map = GameData.getSelectedColony().getMap();
final int width = map.getWidth();
final int height = map.getHeight();
if (x < 0 || y < 0 || x > width || y > height) {
// Coords are out of the map
return false;
}
if (!tileIsPrepared(x, y)) {
// The tile is not prepared
return false;
}
if (BuildingType.ROAD.equals(type)) {
// Roads must be near buildings or other roads
return isNearRoad(x, y) || isNearBuilding(x, y);
} else {
// buildings must be near roads
return isNearRoad(x, y);
}
}
/**
* Tests if there is a road on the 4 squares near the given tile
*
* @param x
* X coordinate of the tile
* @param y
* Y coordinate of the tile
* @return true if a road is found
*/
public static boolean isNearRoad(int x, int y) {
return typeIsNear(x, y, BuildingType.ROAD);
}
/**
* Tests if there is a building on the 4 squares near the given tile
*
* @param x
* X coordinate of the tile
* @param y
* Y coordinate of the tile
* @return true if a building is found
*/
public static boolean isNearBuilding(int x, int y) {
List<Building> buildings = searchNearBuildings(x, y);
return buildings.size() > 0;
}
public static boolean typeIsNear(int x, int y, BuildingType type) {
List<Building> buildings = searchNearBuildings(x, y);
for (Building b : buildings) {
if (type.equals(b.getType())) {
return true;
}
}
return false;
}
private static List<Building> searchNearBuildings(int x, int y) {
List<Building> buildings = new ArrayList<Building>();
safeAdd(buildings, GameData.getSelectedColony().getBuildingAt(x, y - 1));
safeAdd(buildings, GameData.getSelectedColony().getBuildingAt(x + 1, y));
safeAdd(buildings, GameData.getSelectedColony().getBuildingAt(x, y + 1));
safeAdd(buildings, GameData.getSelectedColony().getBuildingAt(x - 1, y));
return buildings;
}
private static void safeAdd(List<Building> list, Building b) {
if (b == null) {
return;
}
list.add(b);
}
/**
* Tests if a tile is impossible to access and prepare
*
* @param x
* X coordinate of the tile
* @param y
* Y coordinate of the tile
* @return true if the tile is impossible to access
*/
public static boolean tileIsImpossible(int x, int y) {
if (x < 0 || y < 0) {
return false;
}
int tileID = GameData.getCurrentMap().getTileId(x, y, ACCESS_LAYER);
return tileID != 0;
}
/**
* Tests if the tile is prepared by a terrabot
*
* @param x
* X coordinate of the tile
* @param y
* Y coordinate of the tile
* @return true if the tile is prepared
*/
private static boolean tileIsPrepared(int x, int y) {
int tileID = GameData.getCurrentMap().getTileId(x, y, 0);
return tileID == BUILDABLE_TILE;
}
/**
* Tests if a tile is preparable by a terrabot
*
* @param x
* X coordinate of the tile
* @param y
* Y coordinate of the tile
* @return true if a terrabot can prepare the tile
*/
public static boolean tileIsPreparable(int x, int y) {
boolean isNotPrepared = !tileIsPrepared(x, y);
boolean isNotImpossible = !tileIsImpossible(x, y);
return isNotPrepared && isNotImpossible;
}
/**
* Update the given tile and set it to the given ID
*
* @param x
* X coordinate of the tile
* @param y
* Y coordinate of the tile
* @param tileID
* the tile ID
*/
public static void setTile(int x, int y, int tileID, Colony c) {
c.getMap().setTileId(x, y, 0, tileID);
}
/**
* Tests if a tile is valid for command center construction
*
* @param x
* X coordinate of the tile
* @param y
* Y coordinate of the tile
* @return true if the tile is OK
*/
public static boolean isValidCommandCenterTile(int x, int y){
TiledMap map = GameData.getSelectedColony().getMap();
final int width = map.getWidth();
final int height = map.getHeight();
if(x < 1 || y < 1 || x > width || y > height){
return false;
}
return true;
}
}