/**
* Unsealed: Whispers of Wisdom.
*
* Copyright (C) 2012 - Juan 'Nushio' Rodriguez
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 of
* the License as published by the Free Software Foundation
*
* 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/>.
*
*/
package net.k3rnel.unsealed.battle;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import net.k3rnel.unsealed.Unsealed;
import net.k3rnel.unsealed.battle.enemies.Bee;
import net.k3rnel.unsealed.battle.enemies.Clam;
import net.k3rnel.unsealed.battle.enemies.Dummy;
import net.k3rnel.unsealed.battle.enemies.Ghost;
import net.k3rnel.unsealed.battle.enemies.Snake;
import net.k3rnel.unsealed.battle.enemies.Terrex;
import net.k3rnel.unsealed.screens.BattleScreen;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Timer;
public class BattleGrid extends Stage {
public final static int battleSetup = 0;
public final static int battleStarted = 1;
public final static int battleWon = 2;
public final static int battleLost = 3;
private float width, height;
protected TextureAtlas atlas;
public static int sizeX;
public static int sizeY;
private static BattleEntity[][] grid;
public static Array<BattleEnemy> enemies;
public static Array<BattleHero> heroes;
private static List<Vector2> unusedPositions;
public static int battleState;
private BattleEnemy tmpBattleEnemy;
private BattleHero tmpBattleHero;
Vector2 tmpSpawnPoint;
public static Timer timer;
public static Random random;
private OrthographicCamera cam;
public BattleGrid(TextureAtlas atlas, float width, float height, int sizeX, int sizeY) {
this.width = width;
this.height = height;
this.atlas = atlas;
setViewport(this.width, this.height, true);
timer = new Timer();
BattleGrid.sizeX = sizeX;
BattleGrid.sizeY = sizeY;
grid = new BattleEntity[sizeX][sizeY];
random = new Random(System.currentTimeMillis());
heroes = new Array<BattleHero>(3);
enemies = new Array<BattleEnemy>((sizeX/2)*sizeY);
cam = new OrthographicCamera(this.width, this.height);
cam.position.set(this.width / 2, this.height / 2, 0);
cam.zoom = 0.8f;
this.setCamera(cam);
}
public static void clearGrid(int x, int y){
if(x<sizeX&&x>=0&&y<sizeY&&y>=0){
grid[x][y] = null;
}
}
public boolean assignEntity(BattleEntity entity){
if(checkGrid(entity.getGridXInt(),entity.getGridYInt())==null){
grid[entity.getGridXInt()][entity.getGridYInt()] = entity;
if(entity instanceof BattleHero){
BattleHero hero = (BattleHero)entity;
heroes.add(hero);
timer.scheduleTask(hero.nextTask(), 0f, 1.2f);
}
if(entity instanceof BattleEnemy){
enemies.add((BattleEnemy)entity);
}
return true;
}else{
return false;
}
}
public static boolean moveEntity(BattleEntity entity, Vector2 pos){
if(pos!=null)
return moveEntity(entity,(int)pos.x,(int)pos.y);
else
return false;
}
public static boolean moveEntity(BattleEntity entity, int newX, int newY){
if(checkGrid(newX,newY)==null){
if(grid[entity.getGridXInt()][entity.getGridYInt()]!=null){
if(grid[entity.getGridXInt()][entity.getGridYInt()]!=entity){
}else{
grid[entity.getGridXInt()][entity.getGridYInt()] = null;
}
}
grid[newX][newY] = entity;
entity.setGrid(newX,newY);
return true;
}else{
return false;
}
}
public Array<BattleEnemy> getEnemies(){
return enemies;
}
/**
* There's probably a bazillion better ways to do it, but this one works.
* @return
*/
public static Vector2 getUnusedPosition(){
unusedPositions = new ArrayList<Vector2>();
for(int x = sizeX/2; x<sizeX;x++){
for(int y = 0; y<sizeY;y++){
if(checkGrid(x,y)==null){
unusedPositions.add(new Vector2(x,y));
}
}
}
if(unusedPositions.size()>0)
return unusedPositions.get(random.nextInt(unusedPositions.size()));
else
return null;
}
@Override
public void act(float delta) {
super.act(delta);
for(int x = 0; x<sizeX;x++){
for(int y = 0;y<sizeY;y++){
if(grid[x][y]!=null){
grid[x][y].act(delta);
if(grid[x][y]!=null){
if(grid[x][y].getHp()<=0){
if(grid[x][y] instanceof BattleHero){
tmpBattleHero = (BattleHero)grid[x][y];
clearGrid(x,y);
heroes.removeValue(tmpBattleHero, false);
checkState();
}
if(grid[x][y] instanceof BattleEnemy){
tmpBattleEnemy = (BattleEnemy)grid[x][y];
if(tmpBattleEnemy instanceof Dummy){
if(tmpBattleEnemy.currentAnimation.isAnimationFinished(tmpBattleEnemy.stateTime)){
clearGrid(x,y);
enemies.removeValue(tmpBattleEnemy,false);
checkState();
}
}else{
clearGrid(x,y);
enemies.removeValue(tmpBattleEnemy,false);
checkState();
}
}
}
}
}
}
}
}
@Override
public void draw() {
super.draw();
this.getSpriteBatch().begin();
for(int x = 0; x<sizeX;x++){
for(int y = 0;y<sizeY;y++){
if(grid[x][y]!=null){
grid[x][y].draw(this.getSpriteBatch(),1);
}
}
}
if(BattleScreen.hero.getHp()>0)
BattleScreen.hero.draw(this.getSpriteBatch(), 1);
this.getSpriteBatch().end();
}
public static int checkState() {
if(enemies.size==0){
battleState = battleWon;
}
if(heroes.size==0){
battleState = battleLost;
}
return battleState;
}
public void spawnEnemies(BattleEnemy... spawnies){
BattleEntity enemy;
enemies = new Array<BattleEnemy>((sizeX/2)*sizeY);
for(int i = 0; i < spawnies.length; i++){
enemy = spawnies[i];
assignEntity(enemy);
timer.scheduleTask(enemy.nextTask(), random.nextInt(5));
}
Gdx.app.log(Unsealed.LOG, "Spawned "+enemies.size+" enemies");
battleState = BattleGrid.battleStarted;
}
public void spawnEnemies(boolean schedule,BattleEnemy... spawnies){
BattleEntity enemy;
enemies = new Array<BattleEnemy>((sizeX/2)*sizeY);
for(int i = 0; i < spawnies.length; i++){
enemy = spawnies[i];
assignEntity(enemy);
if(schedule)
timer.scheduleTask(enemy.nextTask(), random.nextInt(5));
}
Gdx.app.log(Unsealed.LOG, "Spawned "+enemies.size+" enemies");
battleState = BattleGrid.battleStarted;
}
public void spawnEnemies(int speed, BattleEnemy... spawnies ){
BattleEntity enemy;
enemies = new Array<BattleEnemy>((sizeX/2)*sizeY);
for(int i = 0; i < spawnies.length; i++){
enemy = spawnies[i];
assignEntity(enemy);
timer.scheduleTask(enemy.nextTask(), random.nextInt(speed));
}
Gdx.app.log(Unsealed.LOG, "Spawned "+enemies.size+" enemies");
battleState = BattleGrid.battleStarted;
}
public void spawnEnemies(int bonus) {
BattleScreen.round++;
enemies = new Array<BattleEnemy>((sizeX/2)*sizeY);
for(int i = 0; i < random.nextInt(4)+1; i++){
tmpSpawnPoint = getUnusedPosition();
if(tmpSpawnPoint!=null){
if(BattleScreen.round < 4){
if(random.nextInt(100)<40)
tmpBattleEnemy = new Clam(getAtlas(),50, (int)tmpSpawnPoint.x,(int)tmpSpawnPoint.y);
else
tmpBattleEnemy = new Ghost(getAtlas(), 80,(int)tmpSpawnPoint.x,(int)tmpSpawnPoint.y);
}else if(BattleScreen.round>4&&BattleScreen.round<7){
if(random.nextInt(100)<40)
tmpBattleEnemy = new Snake(getAtlas(),70,(int)tmpSpawnPoint.x,(int)tmpSpawnPoint.y);
else if(random.nextInt(100)<50)
tmpBattleEnemy = new Bee(getAtlas(),50,(int)tmpSpawnPoint.x,(int)tmpSpawnPoint.y);
else
tmpBattleEnemy = new Terrex(getAtlas(),100, (int)tmpSpawnPoint.x,(int)tmpSpawnPoint.y);
}else{
if(random.nextInt(100)<30){
tmpBattleEnemy = new Clam(getAtlas(), 60,(int)tmpSpawnPoint.x,(int)tmpSpawnPoint.y);
}else if(random.nextInt(100)<40){
tmpBattleEnemy = new Terrex(getAtlas(), 130,(int)tmpSpawnPoint.x,(int)tmpSpawnPoint.y);
}else if(random.nextInt(100)<40){
tmpBattleEnemy = new Ghost(getAtlas(), 80,(int)tmpSpawnPoint.x,(int)tmpSpawnPoint.y);
}else if(random.nextInt(100)<40){
tmpBattleEnemy = new Snake(getAtlas(), 80,(int)tmpSpawnPoint.x,(int)tmpSpawnPoint.y);
}else{
tmpBattleEnemy = new Bee(getAtlas(),90, (int)tmpSpawnPoint.x,(int)tmpSpawnPoint.y);
}
}
//
// else
//Override below to only spawn this type of enemy
// enemy = new Bee(getAtlas(), (int)spawnPoint.x,(int)spawnPoint.y);
assignEntity(tmpBattleEnemy);
timer.scheduleTask(tmpBattleEnemy.nextTask(), random.nextInt(5));
if(random.nextInt(bonus+1)/3>2&&enemies.size<9){
i--;
}
}
}
if(random.nextInt(bonus)/3>3){
BattleScreen.hero.setHp(BattleScreen.hero.getHp()+30);
}
Gdx.app.log(Unsealed.LOG, "Spawned "+enemies.size+" enemies");
BattleScreen.bonus++;
battleState = BattleGrid.battleStarted;
}
public TextureAtlas getAtlas() {
if( atlas == null ) {
atlas = new TextureAtlas( Gdx.files.internal( "image-atlases/pages-info.atlas" ) );
}
return atlas;
}
public void reset() {
timer = new Timer();
grid = new BattleEntity[sizeX][sizeY];
random = new Random(System.currentTimeMillis());
heroes = new Array<BattleHero>(3);
}
// public static boolean assignOnGrid(int x, int y,BattleEntity entity){
// if(x<sizeX&&x>=0&&y<sizeY&&y>=0){
// if(entity!=null)
// grid[x][y] = entity;
// else
// grid[x][y] = null;
// return true;
// }else{
// return false;
// }
// }
public static BattleEntity checkGrid(int x, int y){
if(x<sizeX&&x>=0&&y<sizeY&&y>=0){
if(grid[x][y] instanceof BattleHero){
if(grid[x][y].isVisible()){
return grid[x][y];
}else{
grid[x][y] = null;
return null;
}
}else if(grid[x][y] instanceof BattleEnemy){
if(grid[x][y].isVisible()){
return grid[x][y];
}else{
grid[x][y] = null;
return null;
}
}else{
grid[x][y] = null;
return null;
}
}else{
return null;
}
}
}