mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-01-30 17:34:23 +07:00
Implemented dynamic ground unit spawning
This commit is contained in:
parent
1c80314cfd
commit
45da578756
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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(){
|
||||
|
||||
|
@ -24,7 +24,7 @@ public class UnitTypes implements ContentList {
|
||||
|
||||
scout = new UnitType("scout", team -> new Scout(scout, team)){{
|
||||
maxVelocity = 1.1f;
|
||||
speed = 0.1f;
|
||||
speed = 0.2f;
|
||||
drag = 0.4f;
|
||||
range = 40f;
|
||||
setAmmo(AmmoTypes.bulletIron);
|
||||
|
@ -251,7 +251,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
||||
drownTime = Mathf.clamp(drownTime);
|
||||
|
||||
if(drownTime >= 1f){
|
||||
damage(health + 1, false);
|
||||
damage(health + 1);
|
||||
}
|
||||
|
||||
float px = x, py = y;
|
||||
|
@ -111,6 +111,7 @@ public abstract class GroundUnit extends BaseUnit {
|
||||
|
||||
protected void moveToCore(){
|
||||
Tile tile = world.tileWorld(x, y);
|
||||
if(tile == null) return;
|
||||
Tile targetTile = world.pathfinder().getTargetTile(team, tile);
|
||||
|
||||
if(tile == targetTile) return;
|
||||
@ -150,7 +151,7 @@ public abstract class GroundUnit extends BaseUnit {
|
||||
}
|
||||
|
||||
//TODO move toward resupply point
|
||||
if(inventory.totalAmmo() + 10 >= inventory.ammoCapacity()){
|
||||
if(isWave || inventory.totalAmmo() + 10 >= inventory.ammoCapacity()){
|
||||
state.set(attack);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package io.anuke.mindustry.ui.fragments;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import io.anuke.mindustry.content.AmmoTypes;
|
||||
import io.anuke.mindustry.content.UnitTypes;
|
||||
import io.anuke.mindustry.content.bullets.TurretBullets;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
@ -79,6 +80,8 @@ public class DebugFragment implements Fragment {
|
||||
new button("spawng", () ->{
|
||||
BaseUnit unit = UnitTypes.scout.create(player.getTeam());
|
||||
unit.set(player.x, player.y);
|
||||
unit.inventory.addAmmo(AmmoTypes.bulletIron);
|
||||
unit.setWave();
|
||||
unit.add();
|
||||
});
|
||||
row();
|
||||
|
@ -1,5 +1,6 @@
|
||||
package io.anuke.mindustry.world.mapgen;
|
||||
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import io.anuke.mindustry.content.blocks.Blocks;
|
||||
import io.anuke.mindustry.content.blocks.StorageBlocks;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
@ -30,11 +31,16 @@ public class ProcGen {
|
||||
double r = sim2.octaveNoise2D(1, 0.6, 1f/70, x, y);
|
||||
double elevation = sim.octaveNoise2D(3, 0.5, 1f/70, x, y) * 4 - 1.2;
|
||||
double edgeDist = Math.max(data.width()/2, data.height()/2) - Math.max(Math.abs(x - data.width()/2), Math.abs(y - data.height()/2));
|
||||
double dst = Vector2.dst(data.width()/2, data.height()/2, x, y);
|
||||
|
||||
double border = 10;
|
||||
double border = 14;
|
||||
|
||||
if(edgeDist < border){
|
||||
elevation += (border - edgeDist)/4.0;
|
||||
elevation += (border - edgeDist)/6.0;
|
||||
}
|
||||
|
||||
if(dst < 20){
|
||||
elevation = 0;
|
||||
}
|
||||
|
||||
if(r > 0.9){
|
||||
|
Loading…
Reference in New Issue
Block a user