package detectiongame.dungen;
import engine.Entity;
import static engine.GfxEngine.loadModel;
import engine.Vec3f;
import engine.model.ObjModel;
import engine.model.OverlayMap;
import java.util.Vector;
/**
*
* @author
* knasaari
*/
public class WallGen {
/** How many cells are there in the world (x*x) */
private final int worldSize;
/** How many tiles there are in one cell (x*x) */
private final int gridSize;
/** Initial cell in x-axis */
private int currentCellx = 7;
/** Initial cell in z-axis */
private int currentCellz = 7;
private int iterations;
private long lastTime = 0;
private World world[][];
private int dungeon[][];
private Grid grid[][];
private OverlayMap minimap;
public WallGen(int worldSize, int gridSize, int iterations){
this.worldSize = worldSize;
this.gridSize = gridSize;
this.iterations = iterations;
world = new World[this.worldSize][this.worldSize];
dungeon = new int[this.worldSize*this.gridSize][this.worldSize*this.gridSize];
grid = new Grid[this.worldSize*this.gridSize][this.worldSize*this.gridSize];
generate();
world[this.currentCellx][this.currentCellz].rebuild();
this.grid = null;
generateMinimap();
}
public void moveCurrentCell(int deltaX, int deltaZ){
if(this.inWorld(this.currentCellx+deltaX, this.currentCellz+deltaZ)){
this.currentCellx += deltaX;
this.currentCellz += deltaZ;
}
}
public void exist(){
for(int x=-1;x<2;x++){
for(int z=-1;z<2;z++){
if(!this.inWorld(this.currentCellx+x, this.currentCellz+z))
continue;
this.world[this.currentCellx+x][this.currentCellz+z].exist();
}
}
}
public void drawMinimap(Vec3f camRot){
this.minimap.draw(this.currentCellx,this.currentCellz,camRot.y);
}
public void update(){
for(int x=0;x<this.worldSize;x++){
for(int z=0;z<this.worldSize;z++){
if(this.numberInList(x,this.currentCellx-1,this.currentCellx,this.currentCellx+1) && this.numberInList(z,this.currentCellz-1,this.currentCellz,this.currentCellz+1)){
if(this.world[x][z].getBuildStatus() == World.EMPTY) {
this.world[x][z].rebuild();
}
}
else{
if(this.world[x][z].getBuildStatus() != World.EMPTY) {
this.world[x][z].free();
}
}
}
}
this.lastTime = System.currentTimeMillis();
while(this.world[this.currentCellx][this.currentCellz].getBuildStatus() != World.READY){
if(System.currentTimeMillis()-this.lastTime > 6) {
return;
}
this.world[this.currentCellx][this.currentCellz].refresh();
}
for(int x=-1;x<=1;x++){
for(int z=-1;z<=1;z++){
if(this.inWorld(this.currentCellx+x, this.currentCellz+z)){
while(this.world[this.currentCellx+x][this.currentCellz+z].getBuildStatus() != World.READY){
if(System.currentTimeMillis()-this.lastTime > 6) {
return;
}
this.world[this.currentCellx+x][this.currentCellz+z].refresh();
}
}
}
}
}
public Vec3f getLightPos(){
return new Vec3f(this.currentCellx*this.gridSize*10f+this.gridSize*5.1f, 5f, this.currentCellz*this.gridSize*10f+this.gridSize*5.1f);
}
private void generateMinimap(){
this.minimap = new OverlayMap(this.dungeon,this.gridSize);
}
private void generate(){
/** Generation starts in the middle of the World */
int currentGridx = (int)(this.currentCellx*this.gridSize), currentGridz = (int)(this.currentCellz*this.gridSize);
double directionRandom;
for(int x=0;x<this.iterations;x++){
directionRandom = Math.random();
if(directionRandom < 0.25){
if(this.inGrid(currentGridx+1, currentGridz))
currentGridx++;
}
else if(directionRandom < 0.5){
if(this.inGrid(currentGridx, currentGridz+1))
currentGridz++;
}
else if(directionRandom < 0.75){
if(this.inGrid(currentGridx-1, currentGridz))
currentGridx--;
}
else{
if(this.inGrid(currentGridx, currentGridz-1))
currentGridz--;
}
this.dungeon[currentGridx][currentGridz] = 1;
}
int sweep[];
int curGx, curGz;
for(int wx=0;wx<this.worldSize;wx++){
for(int wz=0;wz<this.worldSize;wz++){
this.world[wx][wz] = new World(wx+"-"+wz);
for(int gx=0;gx<this.gridSize;gx++){
for(int gz=0;gz<this.gridSize;gz++){
curGx = wx*this.gridSize+gx;
curGz = wz*this.gridSize+gz;
if (this.dungeon[curGx][curGz] != 1){
continue;
}
this.grid[curGx][curGz] = new Grid(curGx*10,curGz*10);
this.grid[curGx][curGz].addEntity();
this.grid[curGx][curGz].back().setModel(loadModel("tile_floor.obj"));
this.world[wx][wz].addEntity(this.grid[curGx][curGz].back());
if(Math.random() < 0.05){
Entity sphere = new Entity();
sphere.setModel(loadModel("rope.obj"));
this.world[wx][wz].addEntity(this.grid[curGx][curGz].addEntity(sphere));
}
sweep = this.genWallType(this.get8Sweep(curGx, curGz));
if(sweep[0] == 0){
this.world[wx][wz].addEntity(this.grid[curGx][curGz].addEntity(this.addWall(sweep[1],0)));
}
else if(sweep[0] == 1){
this.world[wx][wz].addEntity(this.grid[curGx][curGz].addEntity(this.addWall(sweep[1],1)));
this.world[wx][wz].addEntity(this.grid[curGx][curGz].addEntity(this.addWall(sweep[1]+1,3)));
}
else if(sweep[0] == 2){
this.world[wx][wz].addEntity(this.grid[curGx][curGz].addEntity(this.addWall(sweep[1],1)));
this.world[wx][wz].addEntity(this.grid[curGx][curGz].addEntity(this.addWall(sweep[1]+1,2)));
this.world[wx][wz].addEntity(this.grid[curGx][curGz].addEntity(this.addWall(sweep[1]+2,3)));
}
else if(sweep[0] == 3){
this.world[wx][wz].addEntity(this.grid[curGx][curGz].addEntity(this.addWall(sweep[1],0)));
this.world[wx][wz].addEntity(this.grid[curGx][curGz].addEntity(this.addWall(sweep[1]+2,0)));
}
else if(sweep[0] == 4){
this.world[wx][wz].addEntity(this.grid[curGx][curGz].addEntity(this.addWall(sweep[1],2)));
this.world[wx][wz].addEntity(this.grid[curGx][curGz].addEntity(this.addWall(sweep[1]+1,2)));
this.world[wx][wz].addEntity(this.grid[curGx][curGz].addEntity(this.addWall(sweep[1]+2,2)));
this.world[wx][wz].addEntity(this.grid[curGx][curGz].addEntity(this.addWall(sweep[1]+3,2)));
}
sweep = this.genPilarType(this.get8VectorSweep(curGx, curGz));
for(int p=0;p<4;p++){
if(sweep[p] == 1){
this.world[wx][wz].addEntity(this.grid[curGx][curGz].addEntity(this.addWall(p,4)));
}
}
}
}
}
}
}
private Entity addWall(int rot, int mesh){
Entity ent = new Entity();
ObjModel model;
switch(mesh){
case 0:
model = loadModel("tile_wall2.obj");
break;
case 1:
model = loadModel("tile_wall2_corner_0.obj");
break;
case 2:
model = loadModel("tile_wall2_corner_1.obj");
break;
case 3:
model = loadModel("tile_wall2_corner_2.obj");
break;
case 4:
model = loadModel("tile_wall2_pylon.obj");
break;
default:
model = loadModel("tile_wall2.obj");
}
ent.setModel(model);
ent.setRot(0, 90f*rot, 0);
return ent;
}
private boolean inGrid(int x, int y){
return (x < 0 || y < 0 || x >= this.gridSize*this.worldSize || y >= this.gridSize*this.worldSize)? false : true;
}
private boolean inWorld(int x, int y){
return (x < 0 || y < 0 || x >= this.worldSize || y >= this.worldSize)? false : true;
}
private int[] genPilarType(Vector<Integer> sweep){
int ar[] = new int[4];
int tile[] = new int[3];
for(int i=0;i<4;i++){
tile[0] = 0+i*2;
tile[1] = 1+i*2;
tile[2] = 2+i*2;
tile[2] = (tile[2]>7)?0:tile[2];
ar[i] = (sweep.get(tile[0]) == 0 && sweep.get(tile[1]) == 1 && sweep.get(tile[2]) == 0)?1:0;
}
return ar;
}
private int[] genWallType(int sweep){
int ar[] = new int[2];
switch (sweep){
// _
// , |, _ ,|
case 10000000:
case 10000001:
case 11000000:
case 11000001:
case 10000100:
case 10000101:
case 11000100:
case 11000101:
case 10010000:
case 10010001:
case 11010000:
case 11010001:
case 10010100:
case 10010101:
case 11010100:
case 11010101:
ar[0] = 0;
ar[1] = 0;
return ar;
case 1110101:
case 1110100:
case 110101:
case 110100:
case 1100101:
case 1100100:
case 100101:
case 100100:
case 1110001:
case 1110000:
case 110001:
case 110000:
case 1100001:
case 1100000:
case 100001:
case 100000:
ar[0] = 0;
ar[1] = 1;
return ar;
case 1000:
case 1001:
case 1001000:
case 1001001:
case 1100:
case 1101:
case 1001100:
case 1001101:
case 11000:
case 11001:
case 1011000:
case 1011001:
case 11100:
case 11101:
case 1011100:
case 1011101:
ar[0] = 0;
ar[1] = 2;
return ar;
case 1010111:
case 1010110:
case 10111:
case 10110:
case 1000111:
case 1000110:
case 111:
case 110:
case 1010011:
case 1010010:
case 10011:
case 10010:
case 1000011:
case 1000010:
case 11:
case 10:
ar[0] = 0;
ar[1] = 3;
return ar;
// _ _
// |, _|, |_ , |
case 10100000:
case 10100001:
case 11100000:
case 11100001:
case 10100100:
case 10100101:
case 11100100:
case 11100101:
case 10110000:
case 10110001:
case 11110000:
case 11110001:
case 10110100:
case 10110101:
case 11110100:
case 11110101:
ar[0] = 1;
ar[1] = 0;
return ar;
case 101000:
case 101001:
case 1101000:
case 1101001:
case 101100:
case 101101:
case 1101100:
case 1101101:
case 111000:
case 111001:
case 1111000:
case 1111001:
case 111100:
case 111101:
case 1111100:
case 1111101:
ar[0] = 1;
ar[1] = 1;
return ar;
case 1010:
case 1011:
case 1001010:
case 1001011:
case 1110:
case 1111:
case 1001110:
case 1001111:
case 11010:
case 11011:
case 1011010:
case 1011011:
case 11110:
case 11111:
case 1011110:
case 1011111:
ar[0] = 1;
ar[1] = 2;
return ar;
case 10000010:
case 10000011:
case 11000010:
case 11000011:
case 10000110:
case 10000111:
case 11000110:
case 11000111:
case 10010010:
case 10010011:
case 11010010:
case 11010011:
case 10010110:
case 10010111:
case 11010110:
case 11010111:
ar[0] = 1;
ar[1] = 3;
return ar;
// _ _ _
// _|, |_|, |_ , | |
case 10101000:
case 10101001:
case 11101000:
case 11101001:
case 10101100:
case 10101101:
case 11101100:
case 11101101:
case 10111000:
case 10111001:
case 11111000:
case 11111001:
case 10111100:
case 10111101:
case 11111100:
case 11111101:
ar[0] = 2;
ar[1] = 0;
return ar;
case 101010:
case 101011:
case 1101010:
case 1101011:
case 101110:
case 101111:
case 1101110:
case 1101111:
case 111010:
case 111011:
case 1111010:
case 1111011:
case 111110:
case 111111:
case 1111110:
case 1111111:
ar[0] = 2;
ar[1] = 1;
return ar;
case 10001010:
case 10001011:
case 11001010:
case 11001011:
case 10001110:
case 10001111:
case 11001110:
case 11001111:
case 10011010:
case 10011011:
case 11011010:
case 11011011:
case 10011110:
case 10011111:
case 11011110:
case 11011111:
ar[0] = 2;
ar[1] = 2;
return ar;
case 10100010:
case 10100011:
case 11100010:
case 11100011:
case 10100110:
case 10100111:
case 11100110:
case 11100111:
case 10110010:
case 10110011:
case 11110010:
case 11110011:
case 10110110:
case 10110111:
case 11110110:
case 11110111:
ar[0] = 2;
ar[1] = 3;
return ar;
// __
// | |, __
case 11011101:
case 10001000:
case 10001100:
case 10001101:
case 10011101:
case 11001101:
case 11001100:
case 11001000:
case 10001001:
case 10011001:
case 11011001:
case 11011000:
case 11001001:
case 10011100:
case 11011100:
case 10011000:
ar[0] = 3;
ar[1] = 0;
return ar;
case 1110111:
case 1100111:
case 110111:
case 1110110:
case 1110011:
case 1100011:
case 110110:
case 110011:
case 1100110:
case 100110:
case 100011:
case 1100010:
case 110010:
case 1110010:
case 100111:
case 100010:
ar[0] = 3;
ar[1] = 1;
return ar;
// _
// |_|
case 10101010:
case 10101011:
case 11101010:
case 11101011:
case 10101110:
case 10101111:
case 11101110:
case 11101111:
case 10111010:
case 10111011:
case 11111010:
case 11111011:
case 10111110:
case 10111111:
case 11111110:
case 11111111:
ar[0] = 4;
ar[1] = 0;
return ar;
}
ar[0] = -1;
ar[1] = -1;
return ar;
}
private int get8Sweep(int x, int y){
int sweep = 0;
sweep += (this.inGrid(x,y-1) == false || this.dungeon[x][y-1] == 1)?0: 10000000;
sweep += (this.inGrid(x+1,y-1) == false || this.dungeon[x+1][y-1] == 1)?0: 1000000;
sweep += (this.inGrid(x+1,y) == false || this.dungeon[x+1][y] == 1)?0: 100000;
sweep += (this.inGrid(x+1,y+1) == false || this.dungeon[x+1][y+1] == 1)?0: 10000;
sweep += (this.inGrid(x,y+1) == false || this.dungeon[x][y+1] == 1)?0: 1000;
sweep += (this.inGrid(x-1,y+1) == false || this.dungeon[x-1][y+1] == 1)?0: 100;
sweep += (this.inGrid(x-1,y) == false || this.dungeon[x-1][y] == 1)?0: 10;
sweep += (this.inGrid(x-1,y-1) == false || this.dungeon[x-1][y-1] == 1)?0: 1;
return sweep;
}
private Vector<Integer> get8VectorSweep(int x, int y){
Vector<Integer> sweep = new Vector<>();
sweep.add((this.inGrid(x,y-1) == false || this.dungeon[x][y-1] == 1)?0:1);
sweep.add((this.inGrid(x+1,y-1) == false || this.dungeon[x+1][y-1] == 1)?0:1);
sweep.add((this.inGrid(x+1,y) == false || this.dungeon[x+1][y] == 1)?0:1);
sweep.add((this.inGrid(x+1,y+1) == false || this.dungeon[x+1][y+1] == 1)?0:1);
sweep.add((this.inGrid(x,y+1) == false || this.dungeon[x][y+1] == 1)?0:1);
sweep.add((this.inGrid(x-1,y+1) == false || this.dungeon[x-1][y+1] == 1)?0:1);
sweep.add((this.inGrid(x-1,y) == false || this.dungeon[x-1][y] == 1)?0:1);
sweep.add((this.inGrid(x-1,y-1) == false || this.dungeon[x-1][y-1] == 1)?0:1);
return sweep;
}
private static boolean numberInList(int a, int ... numbers){
for(int n:numbers){
if(a == n){
return true;
}
}
return false;
}
}