package com.game.libgdx.roguelikeengine;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.Gdx;
/*
Copyright (C) 2013 Ferran Fabregas (ferri.fc@gmail.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
public class Map {
private Tile tilelayout[][];
private Sprite blockedtile, freetile, rocks_img, fire_img, boulder_img,
bones_img, cross_img, freedungeontile, door_img, web_img,
altar_img, hole_img;
private Sprite waterUL_img, waterUR_img, waterDL_img, waterDR_img,
water_img;
private Sprite upperwall_img, frontwall_img;
private Sprite stair_img;
private Sprite statue1_img, statue2_img, statue3_img;
private Sprite rip_img, tree_img, cofin_img;
private int firstXtile; // defines current section of the map that is shown
// on screen
private int firstYtile; // defines current section of the map that is shown
// on screen
private ArrayList<AccessToLayer> accesspoints;
private boolean isDungeon;
protected int layer = 0;
private boolean initialized = false;
public Map(int layer) {
this.layer = layer;
blockedtile = new Sprite(new Texture(Gdx.files.internal("wall.png")));
freetile = new Sprite(new Texture(Gdx.files.internal("herba.png")));
freedungeontile = new Sprite(new Texture(
Gdx.files.internal("dungeon.png")));
water_img = new Sprite(new Texture(Gdx.files.internal("water.png")));
door_img = new Sprite(new Texture(Gdx.files.internal("door.png")));
web_img = new Sprite(new Texture(Gdx.files.internal("web.png")));
altar_img = new Sprite(new Texture(Gdx.files.internal("altar.png")));
hole_img = new Sprite(new Texture(Gdx.files.internal("hole.png")));
rocks_img = new Sprite(new Texture(Gdx.files.internal("rocks.png")));
bones_img = new Sprite(new Texture(Gdx.files.internal("bones.png")));
boulder_img = new Sprite(new Texture(Gdx.files.internal("boulder.png")));
fire_img = new Sprite(new Texture(Gdx.files.internal("fire.png")));
cross_img = new Sprite(new Texture(Gdx.files.internal("graveyard.png")));
waterDR_img = new Sprite(new Texture(Gdx.files.internal("waterDR.png")));
waterDL_img = new Sprite(new Texture(Gdx.files.internal("waterDL.png")));
waterUR_img = new Sprite(new Texture(Gdx.files.internal("waterUR.png")));
waterUL_img = new Sprite(new Texture(Gdx.files.internal("waterUL.png")));
upperwall_img = new Sprite(new Texture(
Gdx.files.internal("upperwall.png")));
frontwall_img = new Sprite(new Texture(
Gdx.files.internal("frontwall.png")));
cofin_img = new Sprite(new Texture(Gdx.files.internal("cofin.png")));
rip_img = new Sprite(new Texture(Gdx.files.internal("rip.png")));
tree_img = new Sprite(new Texture(Gdx.files.internal("tree.png")));
stair_img = new Sprite(new Texture(Gdx.files.internal("stair.png")));
statue1_img = new Sprite(new Texture(Gdx.files.internal("statue.png")));
statue2_img = new Sprite(new Texture(Gdx.files.internal("statue2.png")));
statue3_img = new Sprite(new Texture(Gdx.files.internal("statue3.png")));
// first tile position must be multiple of tile_size
firstXtile = 0;
firstYtile = 0;
// create tile layout
tilelayout = new Tile[WrapperEngine.TOTAL_X_TILES][WrapperEngine.TOTAL_Y_TILES];
// create access point arraylist
accesspoints = new ArrayList<AccessToLayer>();
}
// **** BEGIN MAP CREATION
public void createrandommap() {
if(!initialized ) init();
// create lakes
for (int num = 0; num < WrapperEngine.NUMBER_OF_LAKES; num++) {
createrandomlake();
}
// create random walls
for (int num = 0; num < (int) (WrapperEngine.NUMBER_OF_WALLS / 2); num++) {
createrandomvwall();
createrandomhwall();
}
// create individual elements
for (int num = 0; num < WrapperEngine.NUMBER_OF_BLOCKING_OBJECTS; num++) {
createblockingelement();
}
// createcementery();
}
protected Map init() {
if(initialized) return this;
// fill with freetiles
for (int xpos = 0; xpos < WrapperEngine.TOTAL_X_TILES; xpos++) {
for (int ypos = 0; ypos < WrapperEngine.TOTAL_Y_TILES; ypos++) {
tilelayout[xpos][ypos] = new Tile(xpos, ypos, false);
}
}
this.initialized = true;
return this;
}
public void createAccessDungeon(int inx, int iny, int outx, int outy,
int layerout) {
// data must be prevalidated, this method don't check it
accesspoints.add(new AccessToLayer(inx, iny, outx, outy, layerout));
tilelayout[inx][iny].settileimage(stair_img);
}
public boolean isAccessPoint(int column, int row) {
for(AccessToLayer atl : accesspoints) {
if(atl.getIncommingX() == column && atl.getIncommingY() == row) return true;
}
return false;
}
public void createAccessOutside(int inx, int iny, int outx, int outy,
int layerout) {
// data must be prevalidated, this method don't check it
accesspoints.add(new AccessToLayer(inx, iny, outx, outy, layerout));
tilelayout[inx][iny].settileimage(stair_img);
}
public ArrayList<AccessToLayer> getLayerAccess() {
return accesspoints;
}
public void createrandomdungeon() {
init();
// create random walls
for (int num = 0; num < (int) (WrapperEngine.NUMBER_OF_WALLS_DUNGEON / 2); num++) {
createrandomvwall();
createrandomhwall();
}
// create individual elements
for (int num = 0; num < WrapperEngine.NUMBER_OF_BLOCKING_OBJECTS; num++) {
createdungeonblockingelement();
}
}
public void createrandomhwall() {
Random randomGenerator = new Random();
int lenght = randomGenerator.nextInt(WrapperEngine.MAX_WALL_LENGTH - 2) + 2;
int start = randomGenerator.nextInt(WrapperEngine.TOTAL_X_TILES
- WrapperEngine.MAX_WALL_LENGTH);
int height = randomGenerator.nextInt(WrapperEngine.TOTAL_Y_TILES - 1);
if (areaisempty(start, height, lenght, 2)) {
for (int xpos = start; xpos < start + lenght; xpos++) {
TileOccupier to = new ObjectTileOccupier(layer, "wall",
"a wall", xpos, height);
TileOccupier to2 = new ObjectTileOccupier(layer, "wall",
"a wall", xpos, height + 1);
tilelayout[xpos][height + 1].block(to);
tilelayout[xpos][height + 1].settileimage(upperwall_img);
tilelayout[xpos][height].block(to2);
tilelayout[xpos][height].settileimage(frontwall_img);
}
}
}
public void createrandomvwall() {
Random randomGenerator = new Random();
int lenght = randomGenerator.nextInt(WrapperEngine.MAX_WALL_LENGTH - 2) + 2;
int start = randomGenerator.nextInt(WrapperEngine.TOTAL_Y_TILES
- WrapperEngine.MAX_WALL_LENGTH);
int width = randomGenerator.nextInt(WrapperEngine.TOTAL_X_TILES);
if (areaisempty(width, start, 1, lenght)) {
for (int ypos = start; ypos < start + lenght; ypos++) {
TileOccupier to = new ObjectTileOccupier(layer, "wall",
"a wall", width, ypos);
tilelayout[width][ypos].block(to);
tilelayout[width][ypos].settileimage(upperwall_img);
}
TileOccupier to = new ObjectTileOccupier(layer, "wall", "a wall",
width, start);
tilelayout[width][start].settileimage(frontwall_img);
tilelayout[width][start].block(to);
}
}
public void createrandomlake() {
Random randomGenerator = new Random();
int lenght = (randomGenerator.nextInt(WrapperEngine.MAX_LAKE_SIZE - 2) + 2);
int start_x = randomGenerator.nextInt(WrapperEngine.TOTAL_X_TILES
- WrapperEngine.MAX_LAKE_SIZE);
int start_y = randomGenerator.nextInt(WrapperEngine.TOTAL_Y_TILES
- WrapperEngine.MAX_LAKE_SIZE);
int width = (randomGenerator.nextInt(WrapperEngine.MAX_LAKE_SIZE - 2) + 2);
if (areaisempty(start_x, start_y, lenght, width)) {
for (int xpos = start_x; xpos < start_x + lenght; xpos++) {
for (int ypos = start_y; ypos < start_y + width; ypos++) {
TileOccupier to = new ObjectTileOccupier(layer, "lake",
"a lake", xpos, ypos);
tilelayout[xpos][ypos].block(to);
tilelayout[xpos][ypos].settileimage(water_img);
}
}
// lake corners
tilelayout[start_x][start_y].settileimage(waterDL_img);
tilelayout[start_x + lenght - 1][start_y].settileimage(waterDR_img);
tilelayout[start_x][start_y + width - 1].settileimage(waterUL_img);
tilelayout[start_x + lenght - 1][start_y + width - 1]
.settileimage(waterUR_img);
}
}
public void createblockingelement() {
Random randomGenerator = new Random();
final int x = randomGenerator.nextInt(WrapperEngine.TOTAL_X_TILES);
final int y = randomGenerator.nextInt(WrapperEngine.TOTAL_Y_TILES);
int element = randomGenerator.nextInt(8);
if (!tilelayout[x][y].isbloqued() && tilelayout[x][y].canPCG()) {
TileOccupier to = null;
if (element == 0) {
tilelayout[x][y].settileimage(rocks_img);
to = new TileOccupier() {
public String getname() {
return "rocks";
}
public String getdescription() {
return "some rock";
}
public int getabsolutecolumn(Map map) {
return x;
}
public int getabsoluterow(Map map) {
return y;
}
public int getlayer() {
return layer;
}
};
}
if (element == 1) {
tilelayout[x][y].settileimage(boulder_img);
to = new TileOccupier() {
public String getname() {
return "boulder";
}
public String getdescription() {
return "a huge rock";
}
public int getabsolutecolumn(Map map) {
return x;
}
public int getabsoluterow(Map map) {
return y;
}
public int getlayer() {
return layer;
}
};
}
if (element == 2) {
tilelayout[x][y].settileimage(bones_img);
to = new TileOccupier() {
public String getname() {
return "skeletal remains";
}
public String getdescription() {
return "the bones of an unfortunate adventurer";
}
public int getabsolutecolumn(Map map) {
return x;
}
public int getabsoluterow(Map map) {
return y;
}
public int getlayer() {
return layer;
}
};
}
if (element == 3) {
tilelayout[x][y].settileimage(rip_img);
to = new TileOccupier() {
public String getname() {
return "grave";
}
public String getdescription() {
return "a grave site";
}
public int getabsolutecolumn(Map map) {
return x;
}
public int getabsoluterow(Map map) {
return y;
}
public int getlayer() {
return layer;
}
};
}
if (element == 4) {
tilelayout[x][y].settileimage(cofin_img);
to = new TileOccupier() {
public String getname() {
return "coffin";
}
public String getdescription() {
return "a coffin";
}
public int getabsolutecolumn(Map map) {
return x;
}
public int getabsoluterow(Map map) {
return y;
}
public int getlayer() {
return layer;
}
};
}
if (element == 5) {
tilelayout[x][y].settileimage(tree_img);
to = new TileOccupier() {
public String getname() {
return "tree";
}
public String getdescription() {
return "a tree";
}
public int getabsolutecolumn(Map map) {
return x;
}
public int getabsoluterow(Map map) {
return y;
}
public int getlayer() {
return layer;
}
};
}
if (element == 6) {
tilelayout[x][y].settileimage(fire_img);
to = new TileOccupier() {
public String getname() {
return "fire";
}
public String getdescription() {
return "a fire";
}
public int getabsolutecolumn(Map map) {
return x;
}
public int getabsoluterow(Map map) {
return y;
}
public int getlayer() {
return layer;
}
};
}
if (element == 7) {
tilelayout[x][y].settileimage(statue1_img);
to = new TileOccupier() {
public String getname() {
return "statue";
}
public String getdescription() {
return "a statue";
}
public int getabsolutecolumn(Map map) {
return x;
}
public int getabsoluterow(Map map) {
return y;
}
public int getlayer() {
return layer;
}
};
}
/*
* if (element==8) { tilelayout[x][y].settileimage(statue2_img); }
* if (element==9) { tilelayout[x][y].settileimage(statue3_img); }
*/
if (to != null)
tilelayout[x][y].block(to);
}
}
public void createdungeonblockingelement() {
Random randomGenerator = new Random();
final int x = randomGenerator.nextInt(WrapperEngine.TOTAL_X_TILES);
final int y = randomGenerator.nextInt(WrapperEngine.TOTAL_Y_TILES);
int element = randomGenerator.nextInt(7);
if (!tilelayout[x][y].isbloqued() && tilelayout[x][y].canPCG()) {
TileOccupier to = null;
if (element == 0) {
tilelayout[x][y].settileimage(altar_img);
to = new TileOccupier() {
public String getname() {
return "altar";
}
public String getdescription() {
return "an altar";
}
public int getabsolutecolumn(Map map) {
return x;
}
public int getabsoluterow(Map map) {
return y;
}
public int getlayer() {
return layer;
}
};
}
if (element == 1) {
tilelayout[x][y].settileimage(hole_img);
to = new TileOccupier() {
public String getname() {
return "hole";
}
public String getdescription() {
return "a hole";
}
public int getabsolutecolumn(Map map) {
return x;
}
public int getabsoluterow(Map map) {
return y;
}
public int getlayer() {
return layer;
}
};
}
if (element == 2) {
tilelayout[x][y].settileimage(web_img);
to = new TileOccupier() {
public String getname() {
return "web";
}
public String getdescription() {
return "a web";
}
public int getabsolutecolumn(Map map) {
return x;
}
public int getabsoluterow(Map map) {
return y;
}
public int getlayer() {
return layer;
}
};
}
if (element == 3) {
tilelayout[x][y].settileimage(cofin_img);
to = new TileOccupier() {
public String getname() {
return "coffin";
}
public String getdescription() {
return "a coffin";
}
public int getabsolutecolumn(Map map) {
return x;
}
public int getabsoluterow(Map map) {
return y;
}
public int getlayer() {
return layer;
}
};
}
if (element == 4) {
tilelayout[x][y].settileimage(rip_img);
to = new TileOccupier() {
public String getname() {
return "RIP";
}
public String getdescription() {
return "a final resting place";
}
public int getabsolutecolumn(Map map) {
return x;
}
public int getabsoluterow(Map map) {
return y;
}
public int getlayer() {
return layer;
}
};
}
if (element == 5) {
tilelayout[x][y].settileimage(tree_img);
to = new TileOccupier() {
public String getname() {
return "tree";
}
public String getdescription() {
return "it's a tree";
}
public int getabsolutecolumn(Map map) {
return x;
}
public int getabsoluterow(Map map) {
return y;
}
public int getlayer() {
return layer;
}
};
}
if (element == 6) {
tilelayout[x][y].settileimage(statue1_img);
to = new TileOccupier() {
public String getname() {
return "statue";
}
public String getdescription() {
return "a statue";
}
public int getabsolutecolumn(Map map) {
return x;
}
public int getabsoluterow(Map map) {
return y;
}
public int getlayer() {
return layer;
}
};
}
/*
* if (element==7) { tilelayout[x][y].settileimage(statue2_img); }
* if (element==8) { tilelayout[x][y].settileimage(statue3_img); }
*/
if (to != null)
tilelayout[x][y].block(to);
}
}
public boolean areaisempty(int xorig, int yorig, int lenght, int width) {
boolean result = true;
for (int x = xorig; x < xorig + lenght; x++) {
for (int y = yorig; y < yorig + width; y++) {
if (tilelayout[x][y].isbloqued() || tilelayout[x][y].canPCG() == false) {
result = false;
}
}
}
return result;
}
public void blocktile(int x, int y, TileOccupier to) {
tilelayout[x][y].block(to);
}
public void unblocktile(int x, int y) {
tilelayout[x][y].unblock();
}
public Tile getfirstavailabletilearround(int x, int y) {
Tile freetile = null;
if (!tilelayout[x - 1][y].isbloqued() && tilelayout[x - 1][y].canPCG() && x > 0) { // is x < 0, this would error before the check, rearrange check
freetile = tilelayout[x - 1][y];
}
if (!tilelayout[x + 1][y].isbloqued() && tilelayout[x + 1][y].canPCG()
&& x < WrapperEngine.TOTAL_X_TILES) {
freetile = tilelayout[x + 1][y];
}
if (!tilelayout[x][y + 1].isbloqued() && tilelayout[x][y + 1].canPCG()
&& y < WrapperEngine.TOTAL_Y_TILES) {
freetile = tilelayout[x][y + 1];
}
if (!tilelayout[x][y - 1].isbloqued() && tilelayout[x][y - 1].canPCG() && y > 0) {
freetile = tilelayout[x][y - 1];
}
return freetile;
}
public void createcementery() {
Random randomGenerator = new Random();
for (int x = 0; x < 11; x = x + 2) {
for (int y = 0; y < 11; y = y + 2) {
int chances = randomGenerator.nextInt(2);
int image = randomGenerator.nextInt(2);
if (chances == 0) {
tilelayout[x][y].block(new ObjectTileOccupier(layer,
"cemetary", "a cemetary", x, y));
if (image == 0) {
tilelayout[x][y].settileimage(cross_img);
}
if (image == 1) {
tilelayout[x][y].settileimage(rip_img);
}
}
}
}
}
// **** END MAP CREATION
// gets
public Tile[][] gettiles() {
return tilelayout;
}
public int getfirstxtile() {
return firstXtile;
}
public int getfirstytile() {
return firstYtile;
}
public boolean isdungeon() {
return isDungeon;
}
public Sprite getfreetile() {
return freetile;
}
public Sprite getfreedungeontile() {
return freedungeontile;
}
// sets / updates
public void setfirstxtile(int value) {
firstXtile = value;
if(firstXtile < 0) firstXtile = 0;
else if(firstXtile > WrapperEngine.TOTAL_X_TILES - (WrapperEngine.ON_SCREEN_TILES_X / 2)) {
firstXtile = WrapperEngine.TOTAL_X_TILES - (WrapperEngine.ON_SCREEN_TILES_X / 2);
}
}
public void setfirstytile(int value) {
firstYtile = value;
if(firstYtile < 0) firstYtile = 0;
else if(firstYtile > WrapperEngine.TOTAL_Y_TILES - (WrapperEngine.ON_SCREEN_TILES_Y / 2) - 1) {
firstYtile = WrapperEngine.TOTAL_Y_TILES - (WrapperEngine.ON_SCREEN_TILES_Y / 2);
}
}
public void scrollright() {
firstXtile = Math.min(tilelayout.length
- WrapperEngine.ON_SCREEN_TILES_X, firstXtile
+ WrapperEngine.ON_SCREEN_TILES_X);
}
public void scrollleft() {
firstXtile = Math.max(firstXtile - WrapperEngine.ON_SCREEN_TILES_X, 0);
}
public void scrolldown() {
firstYtile = Math.min(tilelayout[firstXtile].length
- WrapperEngine.ON_SCREEN_TILES_Y, firstYtile
+ WrapperEngine.ON_SCREEN_TILES_Y);
}
public void scrollup() {
firstYtile = Math.max(firstYtile - WrapperEngine.ON_SCREEN_TILES_Y, 0);
}
public void isdungeon(boolean value) {
isDungeon = value;
}
public boolean istileempty(int x, int y) {
try {
return tilelayout[x][y].isempty();
} catch (ArrayIndexOutOfBoundsException e) {
return false;
}
}
public Tile gettileat(int column, int row) {
if (column < 0 || column > tilelayout.length || row < 0
|| row > tilelayout[column].length)
return null;
else
return tilelayout[column][row];
}
public Tile getleft(Tile tile) {
return getleft(tile.getcolumn(), tile.getrow());
}
public Tile getleft(int column, int row) {
if (column <= 0)
return null;
else
return tilelayout[column - 1][row];
}
public Tile getright(Tile tile) {
return getright(tile.getcolumn(), tile.getrow());
}
public Tile getright(int column, int row) {
if (column >= tilelayout.length - 1)
return null;
else
return tilelayout[column + 1][row];
}
public Tile getup(Tile tile) {
return getup(tile.getcolumn(), tile.getrow());
}
public Tile getup(int column, int row) {
if (row >= tilelayout[column].length - 1)
return null;
else
return tilelayout[column][row + 1];
}
public Tile getdown(Tile tile) {
return getdown(tile.getcolumn(), tile.getrow());
}
public Tile getdown(int column, int row) {
if (row <= 0)
return null;
else
return tilelayout[column][row - 1];
}
public LinkedList<TileOccupier> getoccupiersinrange(int column, int row,
int xRange, int yRange) {
LinkedList<TileOccupier> result = new LinkedList<TileOccupier>();
int halfXRange = xRange / 2;
int halfYRange = yRange / 2;
int sx = column - halfXRange;
int ex = column + halfXRange;
int sy = row - halfYRange;
int ey = row + halfYRange;
Tile tile = null;
TileOccupier to = null;
for (int i = sx; i <= ex; ++i) {
if (i < 0 || i > tilelayout.length)
continue;
for (int j = sy; j <= ey; ++j) {
if (j < 0 || j > tilelayout[i].length)
continue;
tile = tilelayout[i][j];
to = tile.getblocker();
if (to != null)
result.push(to);
}
}
return result;
}
public int getlayer() {
return layer;
}
public List<Tile> getmooreneighbors(Tile tile) {
List<Tile> result = new LinkedList<Tile>();
int column = tile.getcolumn();
int row = tile.getrow();
if(column - 1 >= 0) {
result.add(getleft(tile));
}
if(column + 1 < this.tilelayout.length) {
result.add(getright(tile));
}
if(row - 1 >= 0) {
result.add(getdown(tile));
}
if(row + 1 < this.tilelayout[column].length) {
result.add(getup(tile));
}
return result;
}
public Tile getTileAtPosition(float x, float y) {
int column = this.firstXtile + (int) (x / WrapperEngine.TILE_X_SIZE);
int row = this.firstYtile + (int) (y / WrapperEngine.TILE_Y_SIZE);
return this.getTile(column, row);
}
public Tile getTile(int column, int row) {
if(column < 0 || column >= tilelayout.length || row < 0 || row >= tilelayout[column].length) return null;
return tilelayout[column][row];
}
public boolean isUnreachable(Tile t) {
Tile left = getleft(t);
Tile right = getright(t);
Tile up = getup(t);
Tile down = getdown(t);
return (left == null || left.isbloqued()) &&
(right == null || right.isbloqued()) &&
(up == null || up.isbloqued()) &&
(down == null || down.isbloqued());
}
}