Implemented dynamic ground unit spawning

This commit is contained in:
Anuken
2018-06-20 20:23:43 -04:00
parent 1c80314cfd
commit 45da578756
7 changed files with 121 additions and 17 deletions
@@ -79,8 +79,12 @@ public class Pathfinder {
return paths[Team.red.ordinal()].weights[x][y];
}
public float getValueforTeam(Team team, int x, int y){
return paths == null ? 0 : paths[team.ordinal()].weights[x][y];
}
private boolean passable(Tile tile, Team team){
return (tile.getWallID() == 0 && !(tile.floor().isLiquid && (tile.floor().damageTaken > 0 || tile.floor().drownTime > 0)))
return (tile.getWallID() == 0 && tile.cliffs == 0 && !(tile.floor().isLiquid && (tile.floor().damageTaken > 0 || tile.floor().drownTime > 0)))
|| (tile.breakable() && (tile.getTeam() != team)) || !tile.solid();
}
@@ -173,6 +177,8 @@ public class Pathfinder {
createFor(data.team);
}
state.spawner.checkAllQuadrants();
Log.info("Elapsed calculation time: {0}", Timers.elapsed());
}
+99 -11
View File
@@ -1,19 +1,25 @@
package io.anuke.mindustry.ai;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Bits;
import com.badlogic.gdx.utils.IntArray;
import io.anuke.mindustry.content.AmmoTypes;
import io.anuke.mindustry.content.UnitTypes;
import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.entities.units.Squad;
import io.anuke.mindustry.game.EventType.WorldLoadEvent;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Events;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.*;
public class WaveSpawner {
private static final int quadsize = 15;
private static final int quadsize = 4;
private Bits quadrants;
private IntArray tmpArray = new IntArray();
private Array<FlyerSpawn> flySpawns = new Array<>();
private Array<GroundSpawn> groundSpawns = new Array<>();
@@ -23,24 +29,45 @@ public class WaveSpawner {
}
public void spawnEnemies(){
int spawned = 10;
int groundGroups = Math.min(1 + state.wave / 20, 4);
int flyGroups = Math.min(1 + state.wave / 20, 4);
int spawned = Math.min(state.wave, 6);
int groundGroups = 1 + state.wave / 20;
int flyGroups = 1 + state.wave / 20;
//add extra groups if necessary
for (int i = 0; i < groundGroups - groundSpawns.size; i++) {
GroundSpawn spawn = new GroundSpawn();
findLocation(spawn);
groundSpawns.add(spawn);
}
for (int i = 0; i < flyGroups - flySpawns.size; i++) {
FlyerSpawn spawn = new FlyerSpawn();
spawn.angle = Mathf.random(360f);
findLocation(spawn);
flySpawns.add(spawn);
}
for(GroundSpawn spawn : groundSpawns){
if(state.wave % 20 == 0){
for(FlyerSpawn spawn : flySpawns) findLocation(spawn);
for(GroundSpawn spawn : groundSpawns) findLocation(spawn);
}
for(GroundSpawn spawn : groundSpawns){
checkQuadrant(spawn.x, spawn.y);
if(!getQuad(spawn.x, spawn.y)){
findLocation(spawn);
}
Squad squad = new Squad();
for(int i = 0; i < spawned; i ++){
BaseUnit unit = UnitTypes.scout.create(Team.red);
unit.inventory.addAmmo(AmmoTypes.bulletIron);
unit.setWave();
unit.setSquad(squad);
unit.set(spawn.x * quadsize * tilesize + quadsize * tilesize/2f + Mathf.range(quadsize*tilesize/3f),
spawn.y * quadsize * tilesize + quadsize * tilesize/2f + Mathf.range(quadsize*tilesize/3));
unit.add();
}
}
for(FlyerSpawn spawn : flySpawns){
@@ -62,11 +89,26 @@ public class WaveSpawner {
}
}
public void calculateSpawn(){
public void checkAllQuadrants(){
for(int x = 0; x < quadWidth(); x ++){
for(int y = 0; y < quadHeight(); y ++){
checkQuadrant(x, y);
}
}
}
private void checkQuadrant(int quadx, int quady){
setQuad(quadx, quady, true);
for(int x = 0; x < world.width(); x += quadsize){
for(int y = 0; y < world.height(); y += quadsize){
//TODO quadrant operations, etc
outer:
for (int x = quadx * quadsize; x < world.width() && x < (quadx + 1)*quadsize; x++) {
for (int y = quady * quadsize; y < world.height() && y < (quady + 1)*quadsize; y++) {
Tile tile = world.tile(x, y);
if(tile.solid() || world.pathfinder().getValueforTeam(Team.red, x, y) == Float.MAX_VALUE){
setQuad(quadx, quady, false);
break outer;
}
}
}
}
@@ -74,9 +116,53 @@ public class WaveSpawner {
private void reset(){
flySpawns.clear();
groundSpawns.clear();
quadrants = new Bits(quadWidth() * quadHeight());
}
private boolean getQuad(int quadx, int quady){
return quadrants.get(quadx + quady * quadWidth());
}
private void setQuad(int quadx, int quady, boolean valid){
if(valid){
quadrants.set(quadx + quady * quadWidth());
}else{
quadrants.clear(quadx + quady * quadWidth());
}
}
private void findLocation(GroundSpawn spawn){
spawn.x = -1;
spawn.y = -1;
int shellWidth = quadWidth()*2 + quadHeight() * 2 * 6;
shellWidth = Math.min(quadWidth() * quadHeight() / 4, shellWidth);
Mathf.traverseSpiral(quadWidth(), quadHeight(), Mathf.random(shellWidth), (x, y) -> {
if(getQuad(x, y)){
spawn.x = x;
spawn.y = y;
return true;
}
return false;
});
}
private void findLocation(FlyerSpawn spawn){
spawn.angle = Mathf.random(360f);
}
private int quadWidth(){
return Mathf.ceil(world.width() / (float)quadsize);
}
private int quadHeight(){
return Mathf.ceil(world.height() / (float)quadsize);
}
private class FlyerSpawn{
//square angle
float angle;
FlyerSpawn(){
@@ -85,6 +171,8 @@ public class WaveSpawner {
}
private class GroundSpawn{
//quadrant spawn coordinates
int x, y;
GroundSpawn(){